Link to home
Start Free TrialLog in
Avatar of larockd
larockd

asked on

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

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
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

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.
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)).
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;
   }
}
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;
   }
}
Avatar of larockd

ASKER

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

>> 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;

Does that answer everything?
Avatar of larockd

ASKER

It Sure Does.

Thank you for taking the time...