I have a small memory access problem in my program and I do not find the error, maybe someone could help me.
I have created a new type to store rgb color values.
That type looks like:
typedef struct pixel {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
In my main program I create with calloc a 2D dynamically array, to store the red color information’s.
pixel **pixelvalue = (pixel **) calloc(imginformation.width, sizeof(pixel));
for (i = 0; i < imginformation.width; i++) {
pixelvalue[i] = (pixel *) calloc(imginformation.height, sizeof(pixel));
}
After that I call my function, which read the color values and who should safe them to the array. The function gets as parameter the array.
ReadFile(file, imginformation (Stuff like height and so one), pixelvalue (The calloc array));
In that function I try to write the values with
pixelvalue[i][j].r = (unsigned char)fgetc(in);
Here I get the memory access error, what did I wrong?
Edit
Hi, first of all sorry about the missing language, I was a little bit tired yesterday :).
To understanding, I created an array of pixel and the elements are pointing to another array of pixel? Something like [Point to another 1D array pixel]?
With pixel **pixelvalue = calloc(imginformation.width, sizeof(pixel *)); I create imginformation.width numbers of pointers from type pixel and each pointer show to pixel, right?
It would be awesome if you could explain it a little bit more, if I’m wrong. I would really like to understand it.
@carl-norum What do you mean with:
“you shouldn’t be casting the return values of calloc(). Doing so can
hide bugs with #include that could come back to bite you down the
road”.
? I use the alloc space as parameter for a function, not as return value.
Thanks for your help!
Greetz
You’re not really making a 2D array, you’re making an array of pointers that point to arrays of pixels. That means your first
calloccall should allocate enough space for pointers, not for pixels:You didn’t tag your question with a language, but assuming it’s C (based on your
typedef, which wouldn’t be necessary in C++), you shouldn’t be casting the return values ofcalloc(). Doing so can hide bugs with#includethat could come back to bite you down the road.Edit:
You asked a couple of follow-up questions. The first has been answered pretty well by several other answers, I think, but I’ll try to summarize. The way you’re doing the allocation, you are first going to allocate an array of pointers – each of those pointers is going to point to one row of your array. The rows themselves then need to be allocated – space for each
pixelobject goes there, and the pointers to the rows are stored in the first array of pointers.Your second question, bout the return value from
calloc()is pretty straightforward. If you cast the return value, you can hide implicit declaration bugs from yourself. Since the return type ofcallocisvoid *, if you do something like:Everything works nicely. Now imagine that you didn’t include
stdlib.h, and therefore had no prototype ofcalloc()in your translation unit. That would lead the compiler to assume the signature ofcalloc()to beint calloc(int, int), which isn’t true. The same line of code above would throw you a warning about assuming a default signature for that function. Using a typecast like you have in your code will mask that warning and you might never know you were missing that#includeline.