Problem:
I'm rather sure my issue here is a typical misunderstanding of what's happening with pointers. I'll post what's happening in memory below, because my main goal here is to learn how to debug properly, so this is probably a long post about an otherwise trivial problem.
Here's the code, first:
/*Generate array with 500 to 1000 elements*/
/*In the calling function, I create something like 'int* x;' and pass '&x'*/
void gen_array(int** arr){
int size = rand() % (1001 - 500) + 500;
int i;
*arr = (int*) malloc(size*sizeof(int));
if (*arr == NULL){
printf("Allocation failed\n");
exit(1); //I know this is probably bad form
}
//Fill with some random numbers from 1 to 1000
for (i = 0; i < size; ++i)
*arr[i] = rand() % 1001;
}
It breaks after the first iteration in the for
loop (that is, when i==1
). I'm not sure if I'm allocating wrong with malloc
, or assigning wrong in the loop.
Calling like this:
int* x = NULL; //Tried without '= NULL' as well
gen_array(&x);
The specific error:
Unhandled exception at 0x00265E55 in test.exe: 0xC0000005: Access violation writing location 0xCCCCCCCC.
This is after a first-chance exception at the exact same place, but they are generated at the same line of code (and on the same iteration during execution).
My attempt at analyzing:
If it helps, here's the (relevant) step-by-step from debugging on one attempt (I'm compiling in Visual Studio). I'd like to know how to use this info to help me debug in the future.
- At the start of the calling function,
x = 0xcccccccc
(0xcccccccc=-842150451
seems to be what the compiler uses to fill uninitialized values). After set toNULL
, it's equal to0x00000000
of course. - Calling
gen_array(int** arr)
, since I'm passing a pointer to a pointer, the local 'double pointer' is an address pointing to the NULL pointer:arr=0x0018facc {0x00000000 {???}}
. (This is showing the values of what's being pointed to, since the NULL pointer is pointing to nothing, there's???
) - Call to
malloc
: nowarr=0x0018facc {0x00e97048 {-842150451}}
, so*arr
is pointing to an uninitialized value - First iteration (
i==0
), the number generated is588
, so nowarr=0x0018facc {0x00e97048 {588}}
(that is, the value that*arr
is pointing at is588
)
The next iteration crashes after i
is increased to 1
. Since it's an access violation, I would typically guess that arr+1
isn't expecting to be written to. But the violation location is at 0xCCCCCCCC
, the value that this compiler uses for uninitialized data. Is this because arr+1
is technically uninitialized?
Edit: as @GrzegorzSzpetkowski advised, I tried changing *arr[i]
to (*arr)[i]
. It stopped breaking! but, no new random values are being created/placed into the array (which is why I'm concerned that an array isn't being created at all).
Edit 2: To @EOF's suggestion, I changed the function to return the size so I can call with something like int length = gen_array(&x);
I know I can also try returning an int*
from the function, but I'd like to know what's going on specifically here in the case of passing the pointer from a calling function to be initialized.