简体   繁体   中英

valgrind reporting “Invalid write of size 8”

I'm trying to track down where valgrind is finding this invalid write of size 8 in some code, but am having a hard time seeing it. I'm sure valgrind is correct, I just don't see it. I've reproduced the original error by stripping out the function and doing the same thing, more or less, with the following code:

#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);

}

And the valgrind output is:

$ 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)

The original code has much more than this, but I'm only trying to solve the first problem right now, and will continue investigating other problems after this. I think this is related to the crash that the main application is having right after this point, every single time.

(Someone removed the "C" tag because I had left some C++-isms in, but that seems to me to be missing the purpose, so I removed all C++-isms and got the same results.)

from my analysis of the posted code,

The problem is in the call to memset() (which goes along with most of the valgrind error messages.)

Where writing a sizeof(double) beyond the end of the allocated memory area.

And failing to pass the allocated memory to free() before exiting the program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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