2017-02-11 17 views
0

Я пытаюсь найти, где valgrind находит эту недействительную запись размером 8 в некотором коде, но мне трудно ее видеть. Я уверен, что valgrind верен, я просто этого не вижу. Я воспроизвел оригинальную ошибку зачистки функцию и делает то же самое, более или менее, с помощью следующего кода:valgrind report «Неверная запись размера 8»

#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++ - измы в, но мне кажется, не хватает цели, так что я удалил все C++ -. Измы и получили те же результаты)

+1

Если вы скомпилируете с информацией об отладке, то вывод valgrind должен содержать номера строк в исходном коде. Лучше всего компилировать с отключенными оптимизациями, пытаясь разобраться в этом, но следите за тем, что некоторые проблемы появляются только в оптимизированном коде. –

+0

Тем не менее, учитывая, что вы получаете четыре ошибки, исходящие из 'memset()' вызовов в 'do_realloc()', что существенно сужает пространство поиска. –

+3

Ваша арифметика указателя неверна. 'graph + (* graph_allocated * sizeof (* graph))' должен быть просто 'graph + * graph_allocated'. – kaylum

ответ

0

из моего анализа публикуемую кода,

проблема заключается в вызове memset() (который идет вместе с большинством сообщений об ошибках Valgrind.)

Где пишет sizeof(double) за конец выделенной области памяти ,

И не передать переданную память free() перед выходом из программы.