Reputation: 36237
I am currently looking into a C program to debug where Valgrind was reporting errors.
I've stripped out some of the code into a small project to test where I think the problem is and I believe I've pretty much replicated the problem.
Below is my main function
int main(int argc, char** argv) {
FILE *csvFile = NULL;
csvFile = fopen("test.txt", "wb");
int arraySize = 10;
int i = 0;
targetsStruct *targets;
targetSummaryResultStruct *targetSummaryResult;
targets = malloc(arraySize + 10 * sizeof(targets));
targetSummaryResult = malloc(arraySize + 10 * sizeof(targetSummaryResultStruct));
for (i = 0; i < arraySize; i++)
{
asprintf(&targets[i].target, "TargetStruct: %i", i);
targets[i].rowID = i;
}
for (i = 0; i < arraySize; i++)
{
asprintf(&targetSummaryResult[i].target, "Target: %s", targets[i].target);
free(targets[i].target);
printf("%s\n", targetSummaryResult[i].target);
targetSummaryResult[i].callAttempts = i * 10;
fprintf(csvFile, "%s = %i\n", targetSummaryResult[i].target, targetSummaryResult[i].callAttempts);
free(targetSummaryResult[i].target);
}
fclose(csvFile);
printf("Structure completed");
free(targetSummaryResult);
free(targets);
return (EXIT_SUCCESS);
}
I'm malloc'ing the memory on purpose to say its arraySize + 10. The reason for this is the program I am trying to debug allocates a lot more array elements than are actually needed so I'm testing if this is a potential problem so although the array is 10 elements bigger I'm actually only filling 0 to the arraySize and the next 10 are left.
Below is how my structures are defined
typedef struct TargetSummaryResultStruct
{
char * target;
int callAttempts;
} targetSummaryResultStruct;
typedef struct TargetsStruct
{
char * target;
int rowID;
} targetsStruct;
Below is my valgrind report:
==10244== HEAP SUMMARY:
==10244== in use at exit: 0 bytes in 0 blocks
==10244== total heap usage: 43 allocs, 43 frees, 2,892 bytes allocated
==10244==
==10244== All heap blocks were freed -- no leaks are possible
==10244==
==10244== ERROR SUMMARY: 20 errors from 5 contexts (suppressed: 12 from 8)
==10244==
==10244== 4 errors in context 1 of 5:
==10244== Invalid read of size 4
==10244== at 0x8048619: main (main.c:48)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 2 of 5:
==10244== Invalid read of size 4
==10244== at 0x80485EC: main (main.c:47)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 3 of 5:
==10244== Invalid write of size 4
==10244== at 0x80485C2: main (main.c:41)
==10244== Address 0x40181ec is 2 bytes after a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 4 of 5:
==10244== Invalid read of size 4
==10244== at 0xAF770B: vasprintf (in /lib/libc-2.12.so)
==10244== by 0xAD956A: asprintf (in /lib/libc-2.12.so)
==10244== by 0x80485B2: main (main.c:40)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 5 of 5:
==10244== Invalid write of size 4
==10244== at 0xAF76DD: vasprintf (in /lib/libc-2.12.so)
==10244== by 0xAD956A: asprintf (in /lib/libc-2.12.so)
==10244== by 0x80485B2: main (main.c:40)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
--10244--
--10244-- used_suppression: 12 U1004-ARM-_dl_relocate_object /usr/local/lib/valgrind/default.supp:1391
==10244==
==10244== ERROR SUMMARY: 20 errors from 5 contexts (suppressed: 12 from 8)
I'm not sure how to fix these errors, my understanding of the invalid reads is that I'm trying to access some memory that may have already been free'd but part of the memory wasn't free'd for some reason.
I am new to C.
Upvotes: 1
Views: 2149
Reputation: 1283
There is an arithmetic precedence mistake. *
evaluated before +
, therefore you get a memory block with wrong size. Also at first malloc
, you are allocating memory to hold pointer of targetsStruct
not the struct itself.
targets = malloc((arraySize + 10) * sizeof(targetsStruct)); //change targets to targetsStruct
targetSummaryResult = malloc((arraySize + 10) * sizeof(targetSummaryResultStruct));
Upvotes: 3
Reputation: 29618
These messages indicate that you are accessing the memory past the allocated size.
You have allocated 50 bytes, then access the 4 bytes at offset 48, which includes bytes 48, 49 (legal), and 50, 51 (outside the allocation).
Later on, you access bytes 52, 53, 54, 55, all of which are outside, and valgrind tells you that there are 2 bytes in between the end of the allocation and the start of your access.
Upvotes: 0
Reputation: 20402
The sizes you pass to malloc are incorrect because you're doing sizeof on the wrong thing. You're doing sizeof on the pointer, which will result into the size of the pointer, not the thing it points to. I have no idea why you're adding "arraySize" to the size you're allocating, but the mallocs should look like this:
targets = malloc(arraySize * sizeof *targets);
targetSummaryResult = malloc(arraySize * sizeof *targetSummaryResultStruct);
Upvotes: 0
Reputation: 1977
I think what you meant to do in your malloc
is
targets = malloc((arraySize + 10) * sizeof *targets);
and similarly for other malloc
's.
Upvotes: 1