Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

  1. Define A as a pointer to an address of a pointer that points to address of a double.

  2. 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.

  3. 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.

  4. 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:

enter image description here

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.

like image 354
Altermeris Avatar asked Dec 08 '13 21:12

Altermeris


People also ask

Can we dynamically allocate memory without pointers?

Dynamically allocated memory must be referred to by pointers. the computer memory which can be accessed by the identifier (the name of the variable). integer, 8, stored. The other is the “value” or address of the memory location.

What is the role of pointer in dynamic memory allocation and deallocation?

Deallocation Of Allocated Memory With freeThe function free takes a pointer as parameter and deallocates the memory region pointed to by that pointer. The memory region passed to free must be previously allocated with calloc , malloc or realloc . If the pointer is NULL , no action is taken.

What is a pointer how dynamic memory is allocated?

In C, dynamic memory is allocated from the heap using some standard library functions. The two key dynamic memory functions are malloc() and free(). The malloc() function takes a single parameter, which is the size of the requested memory area in bytes. It returns a pointer to the allocated memory.

Why is dynamic memory allocation better?

Dynamic memory allocation is the process of assigning the memory space during the execution time or the run time. Reasons and Advantage of allocating memory dynamically: When we do not know how much amount of memory would be needed for the program beforehand.


2 Answers

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

like image 80
Glenn Teitelbaum Avatar answered Sep 19 '22 23:09

Glenn Teitelbaum


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.

like image 26
Guntram Blohm Avatar answered Sep 20 '22 23:09

Guntram Blohm