What is the difference between * ptr and ** ptr?

I am encoding a 3D array using triple pointers with malloc. I replaced *ptrdate in (a)

, *ptrdate[i]

and *ptrdate[i]

with *ptrdate

in the code below, as they are all basically Date pointers, but access in different dimensions. I got the same results in both directions.

Question: what's the difference when using sizeof as operand?

typedef struct {
    int day;
} Date;

int main(){
  int i, j, k, count=0;
  int row=3, col=4, dep=5;

  Date ***ptrdate = malloc(row * sizeof *ptrdate); //(a)
  for (i=0; i<row; i++) {
    ptrdate[i] = malloc(col * sizeof *ptrdate[i]); //(b)
    for (j=0; j<col; j++) {
      ptrdate[i][j] = malloc(dep * sizeof *ptrdate[i][j]); //(c)
    }
  }

      

+3


source to share


1 answer


I am coding a 3D array using triple pointers with malloc

.

First of all, there is no need to allocate any array using more than one call malloc

. In fact, this is incorrect, since the word "array" is considered to be denoted by one block of contiguous memory, that is, one allocation. I'll take care of this later, but first, your question is:

Question: what's the difference when used as an operand sizeof

?

The answer, while obvious, is often misunderstood. They are different types of pointers, which coincidentally have the same size and presentation on your system ... but they may have different sizes and presentation on other systems. It's important to remember this feature so you can be sure your code is portable as much as possible.

Given size_t row=3, col=4, dep=5;

, you can declare an array as follows: Date array[row][col][dep];

. I know you cannot use this declaration in this matter ... Live me for a moment. If we are printf("%zu\n", sizeof array);

, it will print row * col * dep * sizeof (Date)

. It knows the full size of the array, including all dimensions ... and that's exactly how many bytes are required when allocating such an array.

printf("%zu\n", sizeof ptrDate);

with ptrDate

, declared as in your code, will produce something completely different, though ... This will result in the size of the pointer (for pointer to pointer to Date

, not to be confused with pointer to Date

or pointer to pointer to Date

) on your system. All sizing information concerning the number of measurements (such as multiplication row * col * dep

) is lost because we did not tell our pointers to support this sizing information. We can still find sizeof (Date)

using sizeof *ptrDate

, though, because we told our code to store the size information associated with the pointer type.



What if we could tell our pointers to keep information about other dimensions (dimensions)? What if we could write ptrDate = malloc(row * sizeof *ptrDate);

and be sizeof *ptrDate

equal col * dep * sizeof (Date)

? That would make distribution easier, wouldn't it?

This brings us back to my introduction: there is a way to accomplish all of these allocations using a single one malloc

. This is a simple pattern to remember, but a tricky pattern to understand (and it is probably appropriate to ask another question):

Date (*ptrDate)[col][dep] = malloc(row * sizeof *ptrDate);

      

Suffice it to say that the usage is still basically the same. You can still use this as ptrDate[x][y][z]

... However, there is one thing that does not seem to be entirely correct and that sizeof ptrDate

still gives the size of the pointer (for the [col] [dep] of array Date

) and sizeof *ptrDate

does not contain the size row

(hence the multiplication in malloc

above ). I'll leave this as an exercise for you to decide if a solution is needed for this ...

free(ptrDate); // Ooops! I must remember to free the memory I have allocated!

      

+2


source







All Articles