valgrind报告“无效写入大小8”

时间:2017-02-11 04:25:51

标签: c valgrind realloc

我正在尝试追踪valgrind在某些​​代码中找到大小为8的无效写入的位置,但我很难看到它。我确定valgrind是正确的,我只是没有看到它。我通过剥离函数并使用以下代码或多或少地执行相同的操作来重现原始错误:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

double* do_realloc(double* orig_graph, int graph_width, int* graph_allocated)
{
    double *graph = (double *)(realloc(orig_graph, (graph_width + 1) * sizeof(*graph)));
    printf("reallocing graph from %d to %d\n", *graph_allocated, graph_width);
    if (!orig_graph) {
        /* initialize */
        memset(graph, 0, graph_width * sizeof(double));
    } else if (graph) {
        if (graph_width > *graph_allocated) {
            /* initialize the new region */
            printf("old region: %p, new region: %p, offset: %d, length: %d\n", orig_graph, graph,
                 (*graph_allocated * sizeof(double)),
                 (graph_width - *graph_allocated) * sizeof(*graph));
            memset(graph + (*graph_allocated * sizeof(*graph)),
                   0,
                   (graph_width - *graph_allocated) * sizeof(*graph));
        }
    } else {
        printf("reallocing FAILED\n");
        graph = orig_graph;
        graph_width = *graph_allocated;
    }

    *graph_allocated = graph_width;
    return graph;

}

int main()
{
    double* graph = NULL;
    int allocated = 0;

    graph = do_realloc(graph, 307, &allocated);
    graph = do_realloc(graph, 300, &allocated);
    graph = do_realloc(graph, 307, &allocated);

}

valgrind输出是:

$ valgrind ./t 
==4250== Memcheck, a memory error detector
==4250== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4250== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4250== Command: ./t
==4250== 
reallocing graph from 0 to 307
reallocing graph from 307 to 300
reallocing graph from 300 to 307
old region: 0x51d4e60, new region: 0x51d5800, offset: 2400, length: 56
==4250== Invalid write of size 8
==4250==    at 0x4C348BE: memset (vg_replace_strmem.c:1094)
==4250==    by 0x4007A9: do_realloc(double*, int, int&) (in /home/dmcbride/tmp/v/t)
==4250==    by 0x400842: main (in /home/dmcbride/tmp/v/t)
==4250==  Address 0x51da300 is 16,672 bytes inside an unallocated block of size 4,185,600 in arena "client"
==4250== 
==4250== Invalid write of size 8
==4250==    at 0x4C348E6: memset (vg_replace_strmem.c:1094)
==4250==    by 0x4007A9: do_realloc(double*, int, int&) (in /home/dmcbride/tmp/v/t)
==4250==    by 0x400842: main (in /home/dmcbride/tmp/v/t)
==4250==  Address 0x51da320 is 16,704 bytes inside an unallocated block of size 4,185,600 in arena "client"
==4250== 
==4250== Invalid write of size 8
==4250==    at 0x4C348F3: memset (vg_replace_strmem.c:1094)
==4250==    by 0x4007A9: do_realloc(double*, int, int&) (in /home/dmcbride/tmp/v/t)
==4250==    by 0x400842: main (in /home/dmcbride/tmp/v/t)
==4250==  Address 0x51da328 is 16,712 bytes inside an unallocated block of size 4,185,600 in arena "client"
==4250== 
==4250== Invalid write of size 8
==4250==    at 0x4C348FD: memset (vg_replace_strmem.c:1094)
==4250==    by 0x4007A9: do_realloc(double*, int, int&) (in /home/dmcbride/tmp/v/t)
==4250==    by 0x400842: main (in /home/dmcbride/tmp/v/t)
==4250==  Address 0x51da330 is 16,720 bytes inside an unallocated block of size 4,185,600 in arena "client"
==4250== 
==4250== 
==4250== HEAP SUMMARY:
==4250==     in use at exit: 2,456 bytes in 1 blocks
==4250==   total heap usage: 4 allocs, 3 frees, 8,336 bytes allocated
==4250== 
==4250== LEAK SUMMARY:
==4250==    definitely lost: 2,456 bytes in 1 blocks
==4250==    indirectly lost: 0 bytes in 0 blocks
==4250==      possibly lost: 0 bytes in 0 blocks
==4250==    still reachable: 0 bytes in 0 blocks
==4250==         suppressed: 0 bytes in 0 blocks
==4250== Rerun with --leak-check=full to see details of leaked memory
==4250== 
==4250== For counts of detected and suppressed errors, rerun with: -v
==4250== ERROR SUMMARY: 7 errors from 4 contexts (suppressed: 0 from 0)

原始代码远不止这些,但我现在只想解决第一个问题,并在此之后继续调查其他问题。我认为这与主要应用程序在此之后每次都发生的崩溃有关。

(有人删除了“C”标签,因为我留下了一些C ++ - isms in,但在我看来似乎没有达到目的,所以我删除了所有C ++ - isms并得到了相同的结果。)

1 个答案:

答案 0 :(得分:0)

来自我对发布的代码的分析,

问题在于对memset()的调用(与大多数valgrind错误消息一起出现。)

在分配的内存区域末尾写sizeof(double)的地方。

在退出程序之前未能将分配的内存传递给free()