Я пытаюсь найти, где 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++ -. Измы и получили те же результаты)
Если вы скомпилируете с информацией об отладке, то вывод valgrind должен содержать номера строк в исходном коде. Лучше всего компилировать с отключенными оптимизациями, пытаясь разобраться в этом, но следите за тем, что некоторые проблемы появляются только в оптимизированном коде. –
Тем не менее, учитывая, что вы получаете четыре ошибки, исходящие из 'memset()' вызовов в 'do_realloc()', что существенно сужает пространство поиска. –
Ваша арифметика указателя неверна. 'graph + (* graph_allocated * sizeof (* graph))' должен быть просто 'graph + * graph_allocated'. – kaylum