The code is using a single contiguous block of memory to hold a 2-D array.
Up vote 4 down vote favorite share g+ share fb share tw.
Being a beginner C/C++ programmer, I am having to spend several hours, trying to decipher the code below: Could someone walk me (step me through the code below for dynamic memory allocation) line by line. Char **alloc_2d_char(const int rows, const int cols) { char *data = (char *)malloc(rows*cols*sizeof(char)); char **array= (char **)malloc(rows*sizeof(char*)); for (int i=0; I C arrays pointers memory-allocation link|improve this question edited Jun 17 '11 at 0:07littleadv12.4k822 asked Jun 16 '11 at 23:52Ashmohan1066 94% accept rate.
It's plain C, not C++ – littleadv Jun 17 '11 at 0:08 Your comments have been immensely useful. Thanks a ton! – Ashmohan Jun 17 '11 at 0:23.
The code is using a single contiguous block of memory to hold a 2-D array. Char *data = (char *)malloc(rows*cols*sizeof(char)); Ok -- this line is allocating space for the entire 2-D array. The 2-D array is rows rows by cols columns.
So the total number of elements is rows * cols. Then you have to multiply that by the amount of space each element takes up, which is sizeof(char) since this is a 2-D array of char. Thus the total amount of memory to be allocated is rows * cols * sizeof(char) which is indeed the argument to malloc.
The malloc call returns a pointer to the allocated memory. Since this memory will be used to hold char, you cast the return value to char *. Char **array= (char **)malloc(rows*sizeof(char*)); array is being declared as type "pointer to pointer to char" because that's what it's going to do.
It'll point to memory that will hold pointers to char. It will be one pointer for each row. So you have to allocate rows * sizeof(char *) memory: the number of pointers times the size of a pointer of the right type.
And since this was allocated to point to pointers to char, we cast the return value to char **. For (int i=0; I Consider a concrete example where rows is 2 and cols is 3. Then you have the block of 6 characters in memory: 012345 And datan (for n from 0 to 5) is the n-th element and &datan is the *address of the n-th element.
So what that loop does in this case is do: array0 = &data0; array1 = &data3; So array0 points to the sub-block starting at 0 and array1 points to the sub-block starting at 3. Then when you add the second subscript you're indexing from the start of that pointer. So array02 means "get the pointer stored in array0.
Find what it points to, then move ahead 2 elements from there. : array0 points to 012 (well, actually points to 0). Then you move two elements ahead and get 2.
Or if you start with array11, array1 points to 345 (and actually points at 3. Move one element ahead and get 4.
Thank you very much. What is the role of **alloc_2d_char? That is, why is everything else enveloped inside this pointer to pointer?
– Ashmohan Jun 17 '11 at 0:18 1 alloc_2d_char is the name of a function that returns a value whose type is char **. If it helps make it clearer, you could think of the function declaration as char** alloc_2d_char() instead of char **alloc_2d_char(). – QuantumMechanic Jun 17 '11 at 0:21 Thanks QM!
One last query. What makes the above dynamic vs. say something like this for defining arrays: double *A = new doublecols; – Ashmohan Jun 17 '11 at 17:57 1 double *A = new doublecols is a dynamic memory allocation. It's just using the C++ way of allocating memory rather than the C way of allocating memory.
The C way would be double *A = (double *) malloc(cols * sizeof(double)) – QuantumMechanic Jun 17 '11 at 18:49 1 That would dynamically allocate a 2-D char array of size locNmyo+2 by locTmyo+2. While the function does hand you back pointer-to-pointer-to-char (char **), C's rules for how pointer dereferencing is done and how arrays are dealt with internally mean that if you have char **array = alloc_2d_char(locNmyo+2, locTmyo+2); you will be able to do arrayij and it will Just Work. Though when you're done with the array you need to properly free it.
First you must free the memory pointed to by &array00 and then you can free the pointers-to-char pointed to by array. – QuantumMechanic Jun 17 '117 at 2:05.
The first malloc is getting memory for the 2D character array. The second malloc is getting memory for rows index. The for loop is setting the pointer to each row.
Finally the row index is returned.
Thanks Richard. I may have need this simplified further...so, OK, as I understand it, "alloc_2D_char" is a pointer to a pointer (and the variables rows and columns are being used here. The parenthesis that follows does what exactly?
*data is a 2D pointer, correct? What is **array? What does that line of code mean...*char **array = (char **).
Finally,What is the role of the for loop? Is there a simpler method to do the exact same thing? – Ashmohan Jun 17 '11 at 0:09.
You can think of the 2-D array that it is creating as an array of single-dimensional arrays. Each row entry points to an array of char that represents the column data for that row. The following is the original code with comments added to attempt to describe each step: char **alloc_2d_char(const int rows, const int cols) { // This allocates the chunk of memory that stores that actual data.
// It is a one single-dimensional array that has rows*cols characters. Char *data = (char *)malloc(rows*cols*sizeof(char)); // This allocates an array of pointers that will then be assigned to the // individual rows (carved out of the previous allocation). Char **array= (char **)malloc(rows*sizeof(char*)); // This assigns each row to the appropriate position in the data array.
// The &(datacols*i) bit of it is the address of a portion in the // memory pointed to by data. The cols*i is the offset to the portion that // represents row i. For (int i=0; i.
Is not hard to decipher... char *data = (char *)malloc(rows*cols*sizeof(char)); simple memory allocation char **array= (char **)malloc(rows*sizeof(char*)); memory allocation of #row char pointers arrayi = &(datacols*i); every arrayi is a pointer, a pointer to datacols*i.
Each * in a declaration refers to one level of pointer indirection. So int ** means a pointer to a pointer to an int. So your function: char **alloc_2d_char(const int rows, const int cols) { returns a pointer to a pointer to a char.
Char *data = (char *)malloc(rows*cols*sizeof(char)); This declares a pointer to a char. The pointer is called data. The initialization calls malloc, which allocates a number of bytes equal to the value of the argument.
This means there are rows*cols*sizeof(char) bytes, which will be equal to rows*cols, since a char is 1 byte. The malloc function returns the pointer to the new memory, which means that data now points to a chunk of memory that's rows*cols big. The (char *) before the call to malloc just casts the new memory to the same type as the pointer data.
Char **array= (char **)malloc(rows*sizeof(char*)); array is a pointer to a pointer to a char. It is also being assigned using malloc. The amount of memory being allocated this time is rows*sizeof(char), which is equal to rows.
This means that array is a pointer to a pointer to a chunk of memory big enough to hold 1 row. For (int i=0; I . .
Rows-1 * And your array pointer will point to a chunk of memory with a list of pointers, each of which points to one of the asterisks in the memory chunk above. Return array; } This just returns your array pointer to a pointer, which matches the return type of the alloc_2d_char function: char **. This means that the caller of the function will essentially obtain an array of pointers, and each of these pointers points to one of the rows of the 2D array.
I mean, assume I define Cols to be 20. So &datacols*i will point to address at location 0 (i.e. , i=0), then address at location 20 (i=1), then at location 40 (i=2) and so on?
Is this thinking correct? – Ashmohan Jun 17 '11 at 16:59 1 Yes, that's right. Memory is allocated in contiguous blocks, which means you could, for example, access every element in the table (left to right, top to bottom), by iterating a pointer from array0 to array0 + (rows * cols) – Dominic Gurto Jun 20 '11 at 0:57.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.