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.

    链接地址: http://www.djcxy.com/p/80224.html

    上一篇: 内存分配是系统调用吗?

    下一篇: 指针指向动态内存分配困惑