gpt4 book ai didi

c - 如何避免 realloc 上的 valgrind 警告?

转载 作者:行者123 更新时间:2023-12-04 19:53:46 30 4
gpt4 key购买 nike

我一直在争论一个似乎很奇怪的 realloc 与 valgrind 无法正常工作的情况。似乎我要么以某种方式分配了太多,要么错误地使用了 realloc。我非常重视 valgrind 错误,这样的错误让我非常担心。

最小工作示例:

#include <stdlib.h>

typedef struct test {
size_t n;
size_t r;
int **ptrs;
} test;

test *new_test() {
test *t = malloc(sizeof(test));
t->n = 0; //number of elements
t->r = 1; //reserve
t->ptrs = calloc(t->r, sizeof(*(t->ptrs))); //calloc inits so we don't have to
return t;
}

void push_back_test(test *t, int *ptr) {
if (t->n == t->r) {
t->r <<= 1;
int **temp_ptr = realloc(t->ptrs, sizeof(t->ptrs) * t->r);
if (temp_ptr) {
t->ptrs = temp_ptr;
} else {
exit(EXIT_FAILURE);
}
//NULL out the rest
for (int **ptri = t->ptrs + t->n; ptri < t->ptrs + t->r; ++ptri) {
(*ptri) = NULL;
}
}
t->ptrs[t->n] = ptr;
++(t->n);
}

int main(int argc, char **argv) {

test *t = new_test();
int *a = calloc(2, sizeof(int)); //calloc inits
int *b = calloc(4, sizeof(int));
int *c = calloc(8, sizeof(int));

push_back_test(t, a);
push_back_test(t, b);
push_back_test(t, c);
push_back_test(t, a);
push_back_test(t, b);

exit(EXIT_SUCCESS);
}

Valgrind 输出:

==26528== Memcheck, a memory error detector
==26528== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26528== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==26528== Command: ./test
==26528==
==26528== Conditional jump or move depends on uninitialised value(s)
==26528== at 0x435A32: __linkin_atfork (in /----/----/test)
==26528== by 0x414905: ptmalloc_init.part.8 (in /----/----/test)
==26528== by 0x414C7F: malloc_hook_ini (in /----/----/test)
==26528== by 0x465B1A: _dl_get_origin (in /----/----/test)
==26528== by 0x436AB4: _dl_non_dynamic_init (in /----/----/test)
==26528== by 0x437916: __libc_init_first (in /----/----/test)
==26528== by 0x40140F: (below main) (in /----/----/test)
==26528==
==26528== Conditional jump or move depends on uninitialised value(s)
==26528== at 0x4104BA: _int_free (in /----/----/test)
==26528== by 0x412C3B: _int_realloc (in /----/----/test)
==26528== by 0x414046: realloc (in /----/----/test)
==26528== by 0x40109D: push_back_test (test.c:20)
==26528== by 0x4011FB: main (test.c:44)
==26528==
==26528== Conditional jump or move depends on uninitialised value(s)
==26528== at 0x410518: _int_free (in /----/----/test)
==26528== by 0x412C3B: _int_realloc (in /----/----/test)
==26528== by 0x414046: realloc (in /----/----/test)
==26528== by 0x40109D: push_back_test (test.c:20)
==26528== by 0x4011FB: main (test.c:44)
==26528==
==26528==
==26528== HEAP SUMMARY:
==26528== in use at exit: 0 bytes in 0 blocks
==26528== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==26528==
==26528== All heap blocks were freed -- no leaks are possible
==26528==
==26528== For counts of detected and suppressed errors, rerun with: -v
==26528== Use --track-origins=yes to see where uninitialised values come from
==26528== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

现在我知道第一个错误可能是我的 libc 的问题,但其余的基本上是在告诉我我没有清空我分配的所有内存并且正在传递垃圾,我相信我不会这样清空新分配的内容。

我已经尝试了很多变体,它们要么(正确地)崩溃要么给出这些消息。我很茫然。

编辑:我遇到问题的原始代码比这更正确。我现在已经修复了 MWE,仍然是一样的。

最佳答案

问题是 glibc 不是 Valgrind-clean。通常,这些错误似乎来自您的 libc.so.6,Valgrind 对其进行了内置抑制。当您静态链接时,这些问题似乎源自您的二进制文件,因此不会被抑制。

您可以通过不静态链接或使用 suppressions 来解决此问题和 suppression files

如果您查看提示的内容,就会发现某些线程本地存储正在与 NULL 进行比较。如果附加调试器,结果会发现事情初始化得很好,问题是误报。

更多信息可以在 this SO thread 找到.

当然,多个评论指出了您使用 new_test 的原始错误和您传递给 realloc 的大小的现有错误。一旦这些问题得到修复,Valgrind 警告仍然存在,这就是原因。

关于c - 如何避免 realloc 上的 valgrind 警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35973187/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com