I'm struggling to learn the C rules of malloc() / free(). Consider the below code, which runs just fine. (On Linux, compiled with GCC.) Specifically, I'm wondering about the arr
array. I get that you have to malloc for all the struct elements within the array... but why don't you have to malloc for the array itself?
#include<stdio.h>
#include<stdlib.h>
#define ARR_SIZE 100
typedef struct containerStruct{
int data1;
int data2;
int data3;
// ...etc...
} container;
int main(){
container* arr[ARR_SIZE]; // Don't I have to malloc this?
int i;
for(i=0; i<ARR_SIZE; i++){
arr[i] = (container*) malloc (sizeof(container)); // I get why I have to malloc() here
}
...do stuff...
for(i=0; i<ARR_SIZE; i++){
free(arr[i]); // I get why I have to free() here
}
// Don't I have to free(arr) ?
return 0;
}
I'm guessing that the container* arr[ARR_SIZE];
line tells the compiler all it needs to know to carve out the space in memory for the array, which is why this code works.
But it still doesn't "feel" right, somehow. When I malloc() something, I'm reserving memory space on the heap, right? But my container* arr[ARR_SIZE];
call creates the array on the stack. So... the array of container* porters exists on the stack, and all of those container* pointers point to a container struct on the heap. Is that correct?
Since ARR_SIZE
is fixed member of the dynamic array *arr[ARR_SIZE]
, you no longer have to allocate memory for the whole array, but just the elements within it, as they are flexible in this case.
When you malloc
any sort of dynamic array, it is safe to always check the return value of the void*
pointer returned from malloc
. Additionally, when you free
each element, it is even safer to set each member to NULL
again, to prevent the pointer from accessing memory again.
Illustrated through this code:
#include <stdio.h>
#include <stdlib.h>
#define ARR_SIZE 100
typedef struct {
int data1;
int data2;
int data3;
// ...etc...
} container_t;
int
main(void) {
container_t *arr[ARR_SIZE];
int i;
for (i = 0; i < ARR_SIZE; i++) {
arr[i] = malloc(sizeof(container_t));
if (arr[i] == NULL) {
printf("Malloc Problem here\n");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < ARR_SIZE; i++) {
if (arr[i]) {
free(arr[i]);
arr[i] = NULL;
}
}
return 0;
}