简体   繁体   English

Valgrind 中大小为 4 的无效读/写

[英]Invalid read/write of size 4 in Valgrind

I am currently looking into a C program to debug where Valgrind was reporting errors.我目前正在研究一个 C 程序来调试 Valgrind 报告错误的地方。

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.我故意分配内存以表示其 arraySize + 10。原因是我试图调试的程序分配的数组元素比实际需要的多得多,所以我正在测试这是否是一个潜在的问题因此,尽管数组大 10 个元素,但实际上我只将 0 填充到 arraySize 中,剩下的 10 个元素。

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:以下是我的 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)

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.我是 C 的新手。

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.同样,首先malloc ,您正在分配内存来保存targetsStruct指针而不是结构本身。

targets = malloc((arraySize + 10) * sizeof(targetsStruct)); //change targets to targetsStruct
targetSummaryResult = malloc((arraySize + 10) * sizeof(targetSummaryResultStruct));

I think what you meant to do in your malloc is我想你的意思是在你的malloc

targets = malloc((arraySize + 10) * sizeof *targets);

and similarly for other malloc 's.和其他malloc类似。

The sizes you pass to malloc are incorrect because you're doing sizeof on the wrong thing.您传递给 malloc 的大小不正确,因为您在错误的事情上执行 sizeof 。 You're doing sizeof on the pointer, which will result into the size of the pointer, not the thing it points to.你在指针上做 sizeof ,这将导致指针的大小,而不是它指向的东西。 I have no idea why you're adding "arraySize" to the size you're allocating, but the mallocs should look like this:我不知道为什么要在分配的大小中添加“arraySize”,但 malloc 应如下所示:

targets = malloc(arraySize * sizeof *targets);
targetSummaryResult = malloc(arraySize * sizeof *targetSummaryResultStruct);

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).您已经分配了 50 个字节,然后访问偏移量 48 处的 4 个字节,其中包括字节 48、49(合法)和 50、51(分配之外)。

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.稍后,您访问字节 52、53、54、55,所有这些都在外部,而 valgrind 会告诉您在分配结束和访问开始之间有 2 个字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM