Confused about Pointers to Pointers and Dynamic Memory Allocation
I am having a difficult time fully understanding what is going on.
This is how I am reading the code at the bottom.
Define A as a pointer to an address of a pointer that points to address of a double.
Allocate 4 blocks of memory on the heap that can each hold an address to a double. Return the address of the first block allocated to A.
Allocate 6 blocks of memory on the heap that can each hold a double data type and return the first block's address for each of the 4 blocks allocated earlier.
Variable A still contains the address of the first block of the four pointers assuming that A[0] changed the value at the address pointed by A rather than A itself.
Now this is where the diagram comes in that is linked at the bottom. Lets say that I wanted to access the data stored in the red block. How would I do so?
Would the following code work?
double data = *(*(A + 3) + 2);
My logic is that A is a pointer and incrementing by 3 should increase the address by the number of bytes that is of the size (double *). Dereferencing the address (A + 3), I would obtain the address of first block (assuming it was not re-assigned). By increasing the resulting address by 2 and dereferencing that address, I should obtain the value at the red block.
So if I understand correctly, 1 + M pointers are being stored in memory. Why? If the goal is to store MxN data, why would I need 1 + M pointers to do so? The extra pointers seem like they would be helpful if I wanted to define rows of different sizes but the objective is to define a rectangular array of data.
const int M = 4;
const int N = 6;
double **A;
A = malloc(M*sizeof(double *));
for (i = 0; i < N; i++) {
A[i]= malloc(N*sizeof(double));
}
Diagram:
Side Note: I am Electrical Engineering student that is unfamiliar with C to some degree and formal programming practices. I know that I'm being pedantic about the such a simple line of code, but I want to be sure that I understand pointers and memory allocation correctly. They are pretty hard to comprehend at first glance. This is part of a matrix multiplication code given to me by my professor and I want to pass the pointer to a function and have it access and modify the correct values in memory. Personally would of liked to see two-dimensional arrays for this code, but I am assuming that there is a good reason.
You can also store this contiguously and just do the math instead of letting the compiler do it for you
So:
double * A = malloc (M * N * sizeof(double));
double get(double * what, cur_x, cur_y, max_x, max_y)
{
return *(what+cur_x*max_y+cur_y);
}
this will save all the indirection since you know the size
If you don't need to allocate sizes dynamically this is what
double A[17][14]
will do for you on the stack
Yes, double data = *(*(A + 3) + 2);
would work, and access the "red" double.
I guess your professor will tell you soon that A[3][2]
works as well, is much easier to read, and preferable to *(*(A + 3) + 2);
Lesson learned (not yet, but what your professor is trying to teach to you): in C, multidimensional arrays are not something like 'a table with N columns and M rows', in C, all arrays are really pointers, and multidimensional arrays are implemented as pointers to pointers. Whenever your write A[3][2]
, *(*(A + 3) + 2)
is what really happens internally. This, in turn, explains why you can't allocate a N*M matrix in one statement; you have to allocate the "row pointers" first, then allocate the "columns" for each of the row pointer.
malloc(M*sizeof(double *))
says: "Give me a pointer to M double pointers." malloc(N*sizeof(double))
says: "Give me a pointer to N doubles." Now notice the bug:
for (i = 0; i < N; i++) {
A[i]= ...;
}
A
points to an array of M double pointers, but you are writing N entries into it (where each entry is a pointer to N doubles). If M > N
you waste space, and if M < N
you use space that you haven't asked permission to write to.
上一篇: 内存分配是系统调用吗?
下一篇: 指针指向动态内存分配困惑