-2

In this piece of code, I noticed themalloc() frees up memory of size of (double *) and double. So when the rest of the code is storing values in DataArray, how does the compiler know where to store those values in the memory?

int rows=100;
int columns=100;

double **DataArray, *DataRow;

DataArray = (double **)malloc(rows *sizeof(double *)+ rows * columns *sizeof(double));

for (i = 0, DataRow = (double *)(DataArray+rows); i < rows; i++, DataRow += columns)
DataArray[i]=DataRow;

Thank You!

Haris
  • 12,120
  • 6
  • 43
  • 70
  • 2
    "...malloc frees up memory.." - sorry you are going to have to explain that a little more, it makes absolutely no sense as written – talonmies Jan 15 '12 at 19:27
  • 1
    What do you mean by "frees up"? – Oliver Charlesworth Jan 15 '12 at 19:28
  • 2
    `malloc` doesn't "free up memory", it allocates it. (I'm not sure I understand your question at all, actually.) – Mat Jan 15 '12 at 19:28
  • 1
    Also, [you should prefer](http://stackoverflow.com/a/605858/129570) `T *p = malloc(n * sizeof(*p))` to `T *p = (T *)malloc(n * sizeof(T))`. – Oliver Charlesworth Jan 15 '12 at 19:29
  • Sorry for my bad wording! I meant to ask about the 4th line. Why does the code allocate for both type double* and double? I thought a variable of type double** could only hold values of type double*. – user1150760 Jan 15 '12 at 19:43
  • it is just memory - you're allocating standard memory. You can put anything in there that you want to using casting or whatnot, and there are caveats(alignment,cpu caching,...) when doing this, but malloc just takes a number of bytes as the argument, what you do with it is up to you. – rsaxvc Jan 15 '12 at 19:50
  • o i see! thank you! i visualized malloc as allocated blocks of memory that is rigid in size. Now I know that it allocates it like one big bucket, where data can flow in like water!...sorry, but how do I choose you as the answer? – user1150760 Jan 15 '12 at 19:54

3 Answers3

1

The compiler does not know how to organize the elements of a two-dimensional array in this way.

That memory is only one-dimensional as the compiler is concerned.

The code you show is explicitly compensating for that by allocating the space for a pointer to each row and enough space for all the rows and columns.

The for loop you posted is initializing all the row pointers, allowing later code to do a two-dimensional lookup by indexing, one-dimensionally, into the row pointers and then indexing again into the desired column.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
0

When the array operations ([]) are used, they generate the needed offsets to access/index the data pointed to by DataArray automatically.

Ex:

DataArray[0] is located at (char*)DataArray+(sizeof(double*) * 0 )bytes
DataArray[1] is located at (char*)DataArray+(sizeof(double*) * 1 )bytes
DataArray[2] is located at (char*)DataArray+(sizeof(double*) * 2 )bytes

Note, the previous pseudocode should not be confused with array arithmetic operations:

DataArray+0

is located at DataArray, but

DataArray+1

is located at DataArray+sizeof(double*)

rsaxvc
  • 1,675
  • 13
  • 20
0

malloc takes an argument of type size_t (basically an integer type matching the 32 or 64 bits architecture you're compiling for). It doesn't "know" what your are allocating, in fact the expression row * sizeof(double *)+ rows * columns * sizeof(double) is here to compute the space you'll need to store rows array of pointer then the arrays.

Note that to store a matrix, you don't need such a complicated and error-prone system. Remove the first part of DataArray containing pointers and access the row, col element using DataArray[row*columns + col]. The integer multiplication is not that a big deal compared to the savings in memory (especially on 64 bits systems). But then again you decide how you balance between CPU and memory.

Nicolas Lehuen
  • 808
  • 1
  • 7
  • 9