Click here to Skip to main content
15,891,184 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have a 2D array definded by pointer like ** ptr.

I need to use malloc to allocate memory to it (**ptr). **ptr is used inside a for loop. When should I need to use malloc/free for this **ptr, inside for loop or outside for loop? Why?


Thanks very much in advanced.
Posted

You can free allocated memory based on the operations you are doing on the allocated memory, if the operation finishes inside the loop then go ahead and free it. If you are concerned with variable length of allocation, try to define null buffer outside the loop and use realloc inside the loop with specific length. Then you can free it outside the loop(as the case may be). Eg:-
C
char * buffer = NULL;
for (int i = 0; i < 100; i++) {
    buffer = realloc(specific_length_int);
    // do some things with buffer
}
free(buffer);
 
Share this answer
 
v2
When? Only you can answer that question, as only you know the requirements of the program. You allocate memory when and where you need to use it, and you free it when you no longer need it. Sometimes you will need to do that inside a loop and sometimes outside. Without a lot more detail of your problem it is impossible to be more precise.
 
Share this answer
 
Comments
DawnLee 28-Oct-12 11:16am    
Thank you.

My codes roughly like those:

int **ptr;


int a = 0;


do {

for (int i=0; i<100; i++){
for (int j = 0; j<80; j++){
ptr[i][j] = a ;
}
}
a++;
}while(a<64 );


Inside do/while loop, **ptr will be used 64 times in the for loop. So, in this situation, where should I use malloc/free for **ptr?
Thanks in advanced.
The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
So you just do it like this:
C++
char** ptr=(char**)malloc(100);
free(ptr);

Don't think inside loop or outside loop, It's just a address of memory!
 
Share this answer
 
Your comments suggest a 3D array rather than a 2D. So if we remove the do {} while (a < 64); block we could fill a 100 x 80 element 2D array thus:
C++
int rows = 100;		// number of rows in each plane
int cols = 80;		// number of columns in each row

// ptr will point to the first element of the array(s)
int **ptr;
// allocate pointers to the rows
ptr = (int**)calloc(rows, sizeof(int*));
// initialise the element content value
int a = 0;

// start iterating the rows in each plane
for (int i=0; i<rows;>{
    // allocate an array of integers for the elements of each column
    ptr[i] = (int*)calloc(cols, sizeof(int));
    // for each column ...
    for (int j = 0; j<cols;>    {
        // set the value of each element in the column to the value of the element counter
        ptr[i][j] = a++;
        // display the indices and value of each element.
        cout << "ptr[" << i << "][" << j << "] = " << a << endl;
        }
}

Note that I used the calloc() function as it makes more sense when allocating anything other than an array of bytes.

The arrays can be freed when the program no longer needs them, and would be in the reverse order of the malloc() calls; I leave that as an exercise for you.
 
Share this answer
 
Comments
DawnLee 28-Oct-12 12:54pm    
Thank you. However, I do need to use do/while loop for the **ptr to be iteratly used in a function. Based on your codes, which way is more reasonable for allocating memory for **ptr and why?


Way 1:



int rows = 100; // number of rows in each plane
int cols = 80; // number of columns in each row

// ptr will point to the first element of the array(s)
int **ptr;
// allocate pointers to the rows
ptr = (int**)calloc(rows, sizeof(int*));
// initialise the element content value
int a = 0;

do{

// start iterating the rows in each plane
for (int i=0; i<rows;>{
// allocate an array of integers for the elements of each column
ptr[i] = (int*)calloc(cols, sizeof(int));
// for each column ...
for (int j = 0; j<cols;> {
// set the value of each element in the column to the value of the element counter
ptr[i][j] = a++;
// display the indices and value of each element.
cout << "ptr[" << i << "][" << j << "] = " << a << endl;
}
}

input(ptr, writ); // just a example of a function read in and write out
output(writ);
}while (a<64);
free(ptr);


Way 2:

int rows = 100; // number of rows in each plane
int cols = 80; // number of columns in each row

// ptr will point to the first element of the array(s)
int **ptr;
// allocate pointers to the rows
// initialise the element content value
int a = 0;

do{

ptr = (int**)calloc(rows, sizeof(int*));

// start iterating the rows in each plane
for (int i=0; i<rows;>{
// allocate an array of integers for the elements of each column
ptr[i] = (int*)calloc(cols, sizeof(int));
// for each column ...
for (int j = 0; j<cols;> {
// set the value of each element in the column to the value of the element counter
ptr[i][j] = a++;
// display the indices and value of each element.
cout << "ptr[" << i << "][" << j << "] = " << a << endl;
}
}

input(ptr, writ); // just a example of a function read in and write out
output(writ);

free(ptr);

}while (a<64);

By Way 1, I allocate memory size to the ptr once outside do/while loop. The ptr will be used repeatedly for 64 times. Then the ptr will be free once outside do/while loop.

By using Way 2, I allocate memory size to ptr and free it at each do/while loop.

So, which way is reasonable to a pointer to be allocated memory.


Thank you very much.
Richard MacCutchan 28-Oct-12 14:00pm    
See my latest suggestion
I think you may be looking for something more like the following. You need to allocate your arrays outside the do {} while(a < 64); loop, otherwise you will be allocating duplicate entries and leaking memory. Then within that loop you set the values in the array and pass it to your other functions. When that loop completes you need to free() the array in each row and finally the array of pointers to the rows.
C++
int rows = 100;		// number of rows in the array
int cols = 80;		// number of columns in each row

// ptr will point to the first element of the array(s)
int **ptr;
// allocate rows, pointers to the columns
ptr = (int**)calloc(rows, sizeof(int*));
for (int i=0; i<rows;>{
    // allocate an array of columns for each row
    ptr[i] = (int*)calloc(cols, sizeof(int));
}
// initialise the loop count
int a = 0;
// start the iteration
do
{
    // for each row ...
    for (int i=0; i<rows;>    {
        // and each column in the row ...
        for (int j = 0; j<cols;>        {
            // set the value of each element in the column to the variable
            ptr[i][j] = a;
            // display the indices and value of each element.
            cout << "ptr[" << i << "][" << j << "] = " << a << endl;
        }
    }
    // when all elements are initialised
    input(ptr, writ);  // just a example of a function read in and write out
    output(writ);
    a++;	// increment to the next iteration
} while(a < 64);

// release the allocated memory
for (int i=0; i<rows;>{
    // free the element array in each row
    free(ptr[i]);
}
// free the array of row pointers
free(ptr);
 
Share this answer
 
Comments
DawnLee 28-Oct-12 14:05pm    
Thank you very much. I will try your way.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900