Linux Valgrind,“未初始化的值”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11246344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Valgrind, "uninitialized value(s)" error
提问by Niklas R
In my C program, I'm allocating memory using malloc()
which does, in contrast to calloc()
, notinitialize the memory and it might still contain garbage. Mostly, in context of the allocation, I do not make any changes to the memory allocated by malloc()
. (For example in a function to initialize a struct that contains a buffer, I do not make changes to the buffer's memory, but later on).
在我的 C 程序中,我正在使用malloc()
which分配内存,相比之下calloc()
,它不会初始化内存并且它可能仍然包含垃圾。大多数情况下,在分配的上下文中,我不会对malloc()
. (例如,在初始化包含缓冲区的结构的函数中,我不会更改缓冲区的内存,但稍后会更改)。
Valgrind gives me a lot of theese errors:
Valgrind 给了我很多这些错误:
- Conditional jump or move depends on uninitialised value(s)
- Use of uninitialised value of size 4
- 条件跳转或移动取决于未初始化的值
- 使用大小为 4 的未初始化值
I am sureto never read from memory that was not initialized in these cases.
在这些情况下,我肯定永远不会从未初始化的内存中读取数据。
Should I ignore them or is it better to initialize the memory on allocation? In case I should ignore them, how can I deactivate this error message in Valgrind?
我应该忽略它们还是在分配时初始化内存更好?如果我应该忽略它们,如何在 Valgrind 中停用此错误消息?
Example 1:
示例 1:
==4253== Conditional jump or move depends on uninitialised value(s)
==4253== at 0x408EB8E: vfprintf (vfprintf.c:1624)
==4253== by 0x4093C2E: printf (printf.c:35)
==4253== by 0x40624D2: (below main) (libc-start.c:226)
==4253== Uninitialised value was created by a heap allocation
==4253== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048938: gk_StreamBufferNode_init (stream.c:101)
==4253== by 0x8048D0D: gk_Stream_bufferWriteProc (stream.c:252)
==4253== by 0x8048665: main (main.c:21)
Code:
代码:
int gk_StreamBufferNode_init(gk_StreamBufferNode* node, int buffer_size,
gk_AllocProc malloc) {
node->buffer = malloc(buffer_size); // line 101
if (node->buffer == NULL) {
return GKIT_FAILEDALLOC;
}
node->next = NULL;
return GKIT_NOERR;
}
Example 2:
示例 2:
==4253== Conditional jump or move depends on uninitialised value(s)
==4253== at 0x402DA39: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048C6E: gk_Stream_bufferWriteProc (stream.c:230)
==4253== by 0x8048665: main (main.c:21)
==4253== Uninitialised value was created by a heap allocation
==4253== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048CE0: gk_Stream_bufferWriteProc (stream.c:248)
==4253== by 0x8048665: main (main.c:21)
Code:
代码:
/* ... */
int available_bytes = binfo->buffer_size - bnode->filled;
int bytes_to_go = size * count;
int offset = 0;
int node_offset = 0;
gk_StreamBufferNode* new_node;
void* destination = NULL;
void* source = NULL;
while (bytes_to_go > 0) {
destination = bnode->buffer + bnode->filled + node_offset;
source = buffer + offset;
if (available_bytes > bytes_to_go) {
memcpy(destination, source, bytes_to_go); // line 230
bnode->filled += bytes_to_go;
offset += bytes_to_go;
node_offset = bytes_to_go;
bytes_to_go = 0;
}
else {
memcpy(destination, source, available_bytes);
offset += available_bytes;
node_offset = 0;
bytes_to_go -= available_bytes;
bnode->filled += available_bytes;
#ifdef DEBUG
assert(bnode->filled == bnode->buffer_size);
#endif // DEBUG
// Allocate a new buffer node.
new_node = (gk_StreamBufferNode*) malloc(sizeof(gk_StreamBufferNode)); // line 248
if (new_node == NULL) {
return GKIT_FAILEDALLOC;
}
int success = gk_StreamBufferNode_init(new_node, binfo->buffer_size,
malloc);
if (success <= GKIT_ERROR) {
free(new_node);
return GKIT_FAILEDALLOC;
}
bnode->next = new_node;
bnode = new_node;
available_bytes = binfo->buffer_size;
}
}
采纳答案by Jens Gustedt
In both cases you just allocate memory without initializing it. The easiest way is to use calloc
instead of malloc
to zero it out. This maybe a good strategy for simple cases, e.g if you later use a buffer
as a string that is to be printed. For more complicated use cases assign values to the individual fields, or even better if you have C99 assign the whole structure from a compound literal:
在这两种情况下,您只需分配内存而不初始化它。最简单的方法是使用calloc
而不是将malloc
其归零。对于简单的情况,这可能是一个很好的策略,例如,如果您稍后使用 abuffer
作为要打印的字符串。对于更复杂的用例,将值分配给单个字段,或者如果您让 C99 从复合文字中分配整个结构,则效果更好:
toto * t = malloc(sizeof(*t));
*t = (toto){ 0 };
回答by Hasturkun
Your code should not be expecting uninitialized memory to contain any value, so having conditional jumps dependent on these shows serious problems.
您的代码不应期望未初始化的内存包含任何值,因此依赖于这些值的条件跳转会显示严重的问题。
You should either be initializing the memory (to some known value, eg. 0
), or not refer to its contents unless they have been initialized.
您应该初始化内存(为某个已知值,例如。0
),或者除非已初始化,否则不要引用其内容。