Initialize 16mb array in C
I am relatively new to "C" and would appreciate your understanding of this topic.
Basically, I'm trying to create a 16MB array and check if the memory content is initialized to zero or "\ 0" or some garbage amount for a school project.
Something like that:
char buffer[16*1024*1024];
I know there is a limit on the size of the program stack and obviously I am getting a segmentation error. Can this be done with malloc ()?
source to share
You can initialize memory with malloc like this:
#define MEM_SIZE_16MB ( 16 * 1024 * 1024 )
char *buffer = malloc(MEM_SIZE_16MB * sizeof(char) );
if (buffer == NULL ) {
// unable to allocate memory. stop here or undefined behavior happens
}
Then you can check the values ββin memory like so (note that this will print for a very long time):
for (int i = 0; i < MEM_SIZE_16MB; i++) {
if( i%16 == 0 ) {
// print a newline and the memory address every 16 bytes so
// it a little easier to read
printf("\nAddr: %08p: ", &buffer[i]);
}
printf("%02x ", buffer[i]);
}
printf("\n"); // one final newline
Remember to free memory on completion
free(buffer);
source to share
Yes, you probably need to do it using malloc()
, and here's why:
Whenever any program (process ... thread ...) starts, it is given a chunk of memory that it uses to store (among other things ...) "local" variables. This area is called the "stack. "It probably won't be big enough to store 16 megabytes.
But there is another area of ββmemory that any program can use: its " heap ". This area (as the name, "heap" is supposed to imply ...) has no intrinsic structure: it is just a pool of memory, and it is usually large enough to store many megabytes. You are just the malloc()
number of bytes you need and free()
those bytes as you pass.
Just define type
which one matches the structure you want to store, then malloc(sizeof(type))
. The storage will come from the heap. (And that's basically what a bunch is for ...)
By the way, there is a library function called calloc()
that will reserve a region that is "known to zero". In addition, it can use clever operating system tricks to do this very efficiently.
source to share
Strictly speaking, the code cannot check if it loses buffer
undefined behavior without risk. If there was a type unsigned char
, then there would be no problems. But char
what can be signed can be a trap value. Trying to work with this value results in UB.
char buffer[16*1024*1024];
// Potential UB
if (buffer[0]) ...
Better to use unsigned char
that can't have trap values.
#define N (16LU*1204*1204)
unsigned char *buffer = malloc(N);
if (buffer) {
for (size_t i = 0; i<N; i++) {
if (buffer[i]) Note_NonZeroValue();
}
}
// Clean-up when done.
free(buffer);
buffer = 0;
The tricky thing about C is that even if it char
doesn't matter the trap, some intelligent compiler might determine that the code is trying something that is UB for the spec and then optimizes if (buffer[0])
to nothing. Reading uninitialized data is not unsigned char
- no, no.
source to share