我目前正在研究一个C程序来调试Valgrind报告错误的位置。
我已经将一些代码删除到一个小项目中,以测试我认为问题所在,并且我相信我几乎已经复制了这个问题。
以下是我的主要功能
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);
}
我是故意将内存写入内存以说明其arraySize + 10.这样做的原因是我试图调试的程序分配了比实际需要的更多的数组元素所以我正在测试是否这是一个潜在的问题,所以尽管数组大10个元素,我实际上只填充0到arraySize,然后剩下10个。
以下是我的结构的定义方式
typedef struct TargetSummaryResultStruct
{
char * target;
int callAttempts;
} targetSummaryResultStruct;
typedef struct TargetsStruct
{
char * target;
int rowID;
} targetsStruct;
以下是我的valgrind报告:
==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)
我不确定如何修复这些错误,我对无效读取的理解是我正在尝试访问一些可能已经免费的内存,但部分内存不是免费的某些原因。
我是C的新手,如果这是一个基本问题,请道歉。
感谢您的帮助。
答案 0 :(得分:2)
存在算术优先级错误。在*
之前评估+
,因此您得到的内存块大小错误。同样在第一个malloc
,您正在分配内存以保存targetsStruct
的指针,而不是结构本身。
targets = malloc((arraySize + 10) * sizeof(targetsStruct)); //change targets to targetsStruct
targetSummaryResult = malloc((arraySize + 10) * sizeof(targetSummaryResultStruct));
答案 1 :(得分:1)
我认为您在malloc
中的意图是
targets = malloc((arraySize + 10) * sizeof *targets);
和其他malloc
类似。
答案 2 :(得分:0)
传递给malloc的大小不正确,因为你正在做错误的大小。你在指针上做了sizeof,这将导致指针的大小,而不是它指向的东西。我不知道为什么你要将“arraySize”添加到你要分配的大小,但malloc应该是这样的:
targets = malloc(arraySize * sizeof *targets);
targetSummaryResult = malloc(arraySize * sizeof *targetSummaryResultStruct);
答案 3 :(得分:0)
这些消息表明您正在访问超出分配大小的内存。
您已经分配了50个字节,然后在偏移48处访问4个字节,其中包括字节48,49(合法)和50,51(在分配之外)。
稍后,您访问字节52,53,54,55,所有这些都在外面,而valgrind告诉您在分配结束和访问开始之间有2个字节。