Reputation: 31
I am working on a school project, trying to create a 2d array based on variables.
int **wagner;
wagner = (int **)calloc((sizeofvstup1 + 1), sizeof(int));
for (int i = 0; i < (sizeofvstup1 + 1); i++) {
wagner[i] =(int *)calloc((sizeofvstup2 + 1), sizeof(int));
}
I use calloc
to get 0 on every array place. But valgrind keeps telling me something like:
Invalid write of size 8 at the "wagner[i]..."
sizeofvstup1
and sizeofvstup2
are variables of the length of the array.
How am I supposed to use calloc
here? Tried many times to change the lines a bit but never helped... :/
What should the code look like to work properly?
Upvotes: 1
Views: 106
Reputation: 70971
As others mentioned the code uses the wrong size for the 1st allocation.
To never having to think again which size to use when allocating there is simple trick:
Given that the result of a memory allocation is always assigned to a pointer just simply request to allocate (multiples of) the size this target pointer is pointing to by doing:
int **wagner;
wagner = calloc(sizeofvstup1 + 1, sizeof *wagner);
for (size_t = 0; i < (sizeofvstup1 + 1); ++i) {
wagner[i] = calloc(sizeofvstup2 + 1, sizeof *wagner[i]);
}
(all other changes to the code are unrelated to this "trick")
This way the code would even survive a change from
int ** wagner;
to let's say
double ** wagner;
without any modifications.
Upvotes: 0
Reputation: 224387
You're not allocating the proper amount of size for the first allocation:
wagner =(int **)calloc((sizeofvstup1+1),sizeof(int));
Here you're allocating space for an array of pointers, but you're passing sizeof(int)
for the element size. If an int
is smaller than an int *
, then you don't have enough space and you end up reading/writing past the end of the array.
Change the element size of the allocation to sizeof(int *)
. Also, don't cast the return value of calloc
:
wagner = calloc((sizeofvstup1 + 1), sizeof(int *));
Upvotes: 3