Solved

Misconfusion OnPointers.  I need a clear explanation, based on actual code provided

Posted on 1998-09-17
9
412 Views
Last Modified: 2012-08-13
I am working on a project with pointers and I havethe code working, but I think I might not be understanding pointers very well.  

I am creating a two dimensional array with dynamic memory allocation and I think I am accessing the pointers wrong.

The question Comes down to how I am sending information into my simulated display.  I have the expanded code below but here is a simplified version.

int* pToInt;

pToInt = (int*) malloc (sizeof(int) * 4) ;
Now how should I place the values into these pointers

pToInt[0] = 19 ;   // Is this placing 19 into pToInt or in this way am I telling it to point to memory address 19.  I ask this because if I
printf("%d",pToInt[0]);  
I get 19.

Should I be placing all  my values in like this

*pToInt[0] = 19 ;
printf("%d",*pToInt[0]);

Please look over my code below and explain.  The code works and gives me the right results I just think I am doing it the wrong way and If I am not can you please explain why that works.



 Here is the code with some comments.

I just cut the relevant code in sections.  

float** pTable = NULL ;

// Allocate Memory For Simulated Multidimensional Array

/*  This next section of code takes a pointer to pointer of type float and allocates iNumberOfSprokets * iNumberChainWheels of them */

 if ( ( pTable = (float **) malloc ( ( sizeof( float * ) * (iNumberOfSprokets * iNumberChainWheels ) ) ) ) == NULL )
 {
  printf(" \n Unable To Allocate Memory For The Table.");
  return 0;
 }

/*  The next section of code allocates enough  memory for pTable[0] to hold 4 * iNumberOfSpokets * iNumberChainWheels of floats.  So right now if there was
3 chain wheels and 2 spokets,I have space to hold 24 floats. */

 if ( ( pTable[0]= (float *) malloc ( ( sizeof( float  ) * (4 * iNumberOfSprokets * iNumberChainWheels ) ) ) ) == NULL )
 {
  printf(" \n Unable To Allocate Memory For The Table.");
  return 0;
 }

 // Set Pointer Locations

/* This next section takes the remaining pointers pTable[iLoopVariable] and assignes them every (sizeof(float) * ColumnWidth Of Table ( Which is 4) * the loopvariable. */

 for ( iLoopVariable = 1 ; iLoopVariable < (iNumberOfSprokets * iNumberChainWheels ) ; iLoopVariable++ )
  {
     
      pTable[iLoopVariable] = pTable[0] + ( ( sizeof(float) * 4 * iLoopVariable ) ) ;
  }

// Put Values Into The pointers;
/*  This next section places the values held into a pointer array and fills the table.  Am I placing the info into the pTable the correct way??   */
 
 gear = 1;  // resetgear

 for (  iLoopVariable = 0; iLoopVariable < iNumberChainWheels ; iLoopVariable++ )
 {
      for (  tempsproket = iNumberOfSprokets; tempsproket > 0 ; tempsproket--)
   {
  pTable[gear-1][0] = gear ;
        pTable[gear-1][1] = pChainWheelSizes[iLoopVariable]  ;
  pTable[gear-1][2] = pSproketSizes[tempsproket-1] ;
  pTable[gear-1][3] = 1.0 ;
  gear++;
   }
 }

  //Display Table To Screen from table pointer

 gear=1;
 

 printf("Table To Screen \n");
  for (  iLoopVariable = 0; iLoopVariable < iNumberChainWheels ; iLoopVariable++ )
 {
 
   
  for (  tempsproket = iNumberOfSprokets; tempsproket > 0 ; tempsproket--)
  {
  printf(" %.0f     %.0f      %.0f    %.0f \n", pTable[gear-1][0],pTable[gear-1][1],pTable[gear-1][2],pTable[gear-1][3]);
     gear++;
  }
 }

Thank You For Your Time.

Darrell
0
Comment
Question by:larockd
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 2
  • 2
9 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 50 total points
ID: 1172976
It LOOKS good.  But I can't promise there aren't errors.  but one major improvement that will tend to get rid of errors is to switch to new and delete.  There is no reason to use malloc or free in C++ except when you are writting overloads to new and delete.  
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172977
pTable = (float **) malloc ( ( sizeof( float * ) * (iNumberOfSprokets * iNumberChainWheels ) ) )

becomes

pTable  = new float * [iNumberOfSprokets * iNumberChainWheels ];

that is less likely to have errors.  For example, if you forgot you wanted a pointer to a pointer and did

pTable  = new float [iNumberOfSprokets * iNumberChainWheels ];

instead, then you would get a compiler error.  Not so with your malloc version.

I would recomend you make this change throughout the code.  I can look at it again when you are done.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172978
opps.   you might have a problem in

for ( iLoopVariable = 1 ; iLoopVariable < (iNumberOfSprokets * iNumberChainWheels ) ; iLoopVariable++ )
     {
         
         pTable[iLoopVariable] = pTable[0] + ( ( sizeof(float) * 4 * iLoopVariable ) ) ;
     }

I'm having trouble following what you want to do.  But I think you have a problem.  Are you aware that when you add or subtract to a pointer, it adjusts the pointer by the specified number times the size of what it points to.  In other words, if a float is 4 bytes.  If you add 2 to a float pointer, it actually increases the pointer's value by 8 (2*sizeof(float)).
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Expert Comment

by:nigel5
ID: 1172979
A very simple class taken from the top of my head. We used a similar thig a while back, we templated the type in the end.

The pointer you are using is an array of ints. When you use the *Iptr, you are dereferencing the first element in the array. the same way you are when you do Iptr[0]. If you do *(Iptr + 4), thats the same as Iptr[4].

class Array2D
{
   private:
   int* data_;
   int cols_;
   int rows_;

   public:
   Array2D(int x, int y)
   :cols_(x), rows_(y),
   data_(new int[rows_*cols_])
   {}
   ~Array2D()
   {delete [] data_;}

   int value(int x, int y) const
   {
      return *(data + ((x*cols_)+y));
   }

   bool value(int x, int y, int val)
   {
      if(x>cols_ || y>rows_) return false;
      *(data + ((x*cols_)+y)) = val;
      return true;
   }
}
0
 

Expert Comment

by:nigel5
ID: 1172980
A very simple class taken from the top of my head. We used a similar thig a while back, we templated the type in the end.

The pointer you are using is an array of ints. When you use the *Iptr, you are dereferencing the first element in the array. the same way you are when you do Iptr[0]. If you do *(Iptr + 4), thats the same as Iptr[4].

class Array2D
{
   private:
   int* data_;
   int cols_;
   int rows_;

   public:
   Array2D(int x, int y)
   :cols_(x), rows_(y),
   data_(new int[rows_*cols_])
   {}
   ~Array2D()
   {delete [] data_;}

   int value(int x, int y) const
   {
      return *(data + ((x*cols_)+y));
   }

   bool value(int x, int y, int val)
   {
      if(x>cols_ || y>rows_) return false;
      *(data + ((x*cols_)+y)) = val;
      return true;
   }
}
0
 

Author Comment

by:larockd
ID: 1172981
I am taking a digital logic class and we are not allowed to use C++ or I would have.  Even the way we were to define the memory for this project was given.  The scope in which we do this project is very strict.

When the user enters in the number of sprokets and number of chain wheels this gives us how rows we will have in the table.  The  table has 4 columns, gear number, sproket, chain wheel, and the calculation from them.

So when you declared the frist pointer to pointer of type float.  You used that pointer to allocate all the memory needed for the table.  Then you used the resulting pointers to point to areas in that memory.  Example

float **pTable = allocate memory for 4 rows
*table[0] = allocate memory to hold all values in the tables ( 4 columns x chainteeth x sprockets )
Now Table one has allocated lets say 64 bytes.  Now we will use the remaining pointers to point to various spots in that allcoated memory.
pTable[1] = pTable[0] + 16 ;
pTable[2] = pTable[0] + 32 ;


..etc thats what this code does
for ( iLoopVariable = 1 ; iLoopVariable < (iNumberOfSprokets * iNumberChainWheels ) ;
      iLoopVariable++ )
           {
           
               pTable[iLoopVariable] = pTable[0] + ( ( sizeof(float) * 4 * iLoopVariable ) ) ;
           }


The question I need answered is what I asked at the top about certain assignment statements being equal for pointers..

I graded the question to give you the points, and i hope you glance over the top and look  at what is causing me some confusion...

Here below is a sample


                                      C++ Language Question
    Title: "Misconfusion OnPointers. I need a clear explanation, based on actual code provided"

    From: larockd
                                                      Date: Thursday, September 17 1998 - 02:36PM PDT
    Status: Answered.(You must now evaluate our expert's response)
    Points: 50 Points (Easy)


    I am working on a project with pointers and I havethe code working, but I think I might not be
    understanding pointers very well.  

    I am creating a two dimensional array with dynamic memory allocation and I think I am accessing the
    pointers wrong.

    The question Comes down to how I am sending information into my simulated display.  I have the
    expanded code below but here is a simplified version.

    int* pToInt;

    pToInt = (int*) malloc (sizeof(int) * 4) ;
    Now how should I place the values into these pointers

    pToInt[0] = 19 ;   // Is this placing 19 into pToInt or in this way am I telling it to point to memory address
    19.  I ask this because if I
    printf("%d",pToInt[0]);  
    I get 19.

    Should I be placing all  my values in like this

    *pToInt[0] = 19 ;
    printf("%d",*pToInt[0]);

    Please look over my code below and explain.  The code works and gives me the right results I just think
    I am doing it the wrong way and If I am not can you please explain why that works.

Thanks
Darrell

0
 
LVL 22

Expert Comment

by:nietod
ID: 1172982
>> we are not allowed to use C++
You might want to mention that next time, or ask in the C (not ++) topic area.

pToInt = (int*) malloc (sizeof(int) * 4) ;
   Now how should I place the values into these pointers

>>The question I need answered is what I asked at the top about
>> certain assignment statements being equal for pointers.
Sorry, my attention span is about 2 minutes.  By the time is was at the bottom of the question the top was long since forgotten.

>>  int* pToInt;
>>  pToInt = (int*) malloc (sizeof(int) * 4) ;
>>  pToInt[0] = 19 ;   // Is this placing 19 into pToInt or in this way am
>> I telling it to point to memory address 19.  
You are storing 19 in the integer that pToInt points to.  This does not change pToInt, it changes what it points to.  To change pToInt to point elsewhere you would use the & operator, like

int SomeInt;
pToInt = &SomeInt;

or to put a specific address in, you could do.

pToInt = *(int * *) &19; // point to address 19.

Note that in the above code, pToInt does not have an associated  * or []  operator.  Those would make the change occur to what pToInt points to.  without them, the change is to pToInt itself.

Note that C++ (and C) treat arrays and pointers as 99% interchangably (other than in their allocation and destruction).  Thus pToInt can be considered an array of 4 ints or a pointer to 4 ints.  It doesn't matter.  If I want to place 1, 2, 3, and 4 in the array, I can use array syntax, like

pToInt[0] = 1;
pToInt[1] = 2;
pToInt[2] = 3;
pToInt[3] = 4;

or pointer syntax like

*pToInt = 1;
*(pToInt+1) = 2;
*(pToInt+2) = 3;
*(pToInt+3) = 4;

0
 
LVL 22

Expert Comment

by:nietod
ID: 1172983
Does that answer everything?
0
 

Author Comment

by:larockd
ID: 1172984
It Sure Does.

Thank you for taking the time...
0

Featured Post

Want Experts Exchange at your fingertips?

With Experts Exchange’s latest app release, you can now experience our most recent features, updates, and the same community interface while on-the-go. Download our latest app release at the Android or Apple stores today!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question