Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C valgrind在打印分配的字符串时报告错误_C_Printf_Valgrind - Fatal编程技术网

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

C valgrind在打印分配的字符串时报告错误,c,printf,valgrind,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); } ==1421== Memcheck, a memory error detector ==1421== Copyrigh

代码如下:

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

int main()
{
    char* buf = malloc(3);
    strcpy(buf, "hi");
    printf("%s\n", buf);
    free(buf);
}
==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)
错误信息如下:

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

int main()
{
    char* buf = malloc(3);
    strcpy(buf, "hi");
    printf("%s\n", buf);
    free(buf);
}
==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)
同样非常奇怪的是,如果我使用以下内容(仅多出一个空格),valgrind不会报告更多错误:


有人能帮我吗?

我已经在自己的机器上运行了它,没有出现错误:

==61755== Memcheck, a memory error detector
==61755== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==61755== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==61755== Command: ./a.out
==61755==
hi
==61755==
==61755== HEAP SUMMARY:
==61755==     in use at exit: 0 bytes in 0 blocks
==61755==   total heap usage: 1 allocs, 1 frees, 3 bytes allocated
==61755==
==61755== All heap blocks were freed -- no leaks are possible
==61755==
==61755== For counts of detected and suppressed errors, rerun with: -v
==61755== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

这是一个bug,但并非在所有机器上都可以复制

在某些机器上,gcc使用例如
put()
优化simple
printf()
,这可能涉及无效读取(或者valgrind认为是这样)

如果这真的很重要,您可以将
printf
格式“复杂化”。
%s
\n
之间的空格可以

下面是一个类似的错误:


这个答案结合了讨论中的评论。谢谢大家!

但我使用的是g++编译器,如果没有强制转换,错误将类似于“无法从void*转换为char*”。我有一些其他的原因,为什么我不使用“新”而不是“Maloc”。你不应该把C代码建立成C++,然后问它的问题,好像它是C。C和C++之间有区别。@放松我起初是怀疑的,但是我实际上运行了代码(编译为<代码> GCC < /Cord>),并且它确实产生了警告,但仅当在
%s
之后使用
\n
时。“地址0x41b3028是一个大小为3 alloc'd的块中的0字节”。我认为您正在被
put
(其中gcc替换了一个微不足道的
printf
)所咬,使用优化的
strlen
,在本例中是执行8字节读取,从而读取超过分配区域的末尾。您可能想将此报告为错误,所以我的库或编译器有问题?如果有必要的话,我正在使用用于x86_64的gcc多库。