打印分配的字符串时,valgrind报告错误

pet*_*ter 6 c printf valgrind

代码在这里:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char* buf = malloc(3);
    strcpy(buf, "hi");
    printf("%s\n", buf);
    free(buf);
}
Run Code Online (Sandbox Code Playgroud)

它编译为:

gcc a.c && valgrind ./a.out
Run Code Online (Sandbox Code Playgroud)

错误消息在这里:

==1421== Memcheck, a memory error detector
==1421== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==1421== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==1421== Command: ./a.out
==1421== 
==1421== Invalid read of size 8
==1421==    at 0x4EA96C1: ??? (in /lib/libc-2.14.1.so)
==1421==    by 0x4E92D3B: puts (in /lib/libc-2.14.1.so)
==1421==    by 0x4005BB: main (in /home/peter/a.out)
==1421==  Address 0x51b4040 is 0 bytes inside a block of size 3 alloc'd
==1421==    at 0x4C2740D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1421==    by 0x400595: main (in /home/peter/a.out)
==1421== 
hi
==1421== 
==1421== HEAP SUMMARY:
==1421==     in use at exit: 0 bytes in 0 blocks
==1421==   total heap usage: 1 allocs, 1 frees, 3 bytes allocated
==1421== 
==1421== All heap blocks were freed -- no leaks are possible
==1421== 
==1421== For counts of detected and suppressed errors, rerun with: -v
==1421== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 6 from 6)
Run Code Online (Sandbox Code Playgroud)

如果我使用以下(仅一个空格),valgrind报告不再有错误也是非常奇怪的:

printf("%s \n", buf);
Run Code Online (Sandbox Code Playgroud)

有人请帮帮我吗?

pet*_*ter 3

这是一个错误,但并非在所有机器上都能重现。

在某些机器上,gcc 会printf()使用例如进行简单优化puts(),这可能会涉及无效读取(或者只是 valgrind 这么认为)。

如果确实重要,您可以使printf格式“复杂化”。%s和之间有一个空格\n就可以了。

这是一个类似的错误:C strings、strlen 和 Valgrind

这个答案结合了讨论中的评论。谢谢你们!