Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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弦、strlen和Valgrind_C_String_Valgrind_Strlen - Fatal编程技术网

C弦、strlen和Valgrind

C弦、strlen和Valgrind,c,string,valgrind,strlen,C,String,Valgrind,Strlen,我在试着理解Valgrind为什么会吐出来: ==3409== Invalid read of size 8 ==3409== at 0x4EA3B92: __GI_strlen (strlen.S:31) 每当我在动态分配的字符串上应用strlen时 下面是一个简短的测试用例: #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *hello

我在试着理解Valgrind为什么会吐出来:

==3409== Invalid read of size 8
==3409==    at 0x4EA3B92: __GI_strlen (strlen.S:31)
每当我在动态分配的字符串上应用strlen时

下面是一个简短的测试用例:

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

int main() {

  char *hello = "Hello World";
  char *hello2;

  /* Step 1 */
  printf("Step 1\n");
  printf("strlen : %lu\n",(unsigned long)strlen(hello));

  /* Step 2 */
  hello2 = calloc(12,sizeof(char));
  hello2[0] = 'H';
  hello2[1] = 'e';
  hello2[2] = 'l';
  hello2[3] = 'l';
  hello2[4] = 'o';
  hello2[5] = ' ';
  hello2[6] = 'W';
  hello2[7] = 'o';
  hello2[8] = 'r';
  hello2[9] = 'l';
  hello2[10] = 'd';
  hello2[11] = 0;  

  printf("Step 2\n");
  printf("strlen : %lu\n",(unsigned long)strlen(hello2));
  free(hello2);

  return 0;
}

避免这些警告的正确方法是什么?它们是真正的警告吗?

我猜您的strlen实现已经过优化,它一次读取8个字节,并测试64位字中任何位置的第一个零字节(可能使用MMX/SSE)。这意味着您的12字节字符串示例读取的是字符串末尾以外的4个字节。这是否是strlen实现中的一个bug还有争议。我想你只能忽略它。或者确保字符串分配总是8字节的倍数。

这很可能与此错误报告有关:


正如Paul已经建议的,intel平台上的strlen()可以选择使用SSE优化来加速strlen和friends。这种加速需要在分配的块后面进行安全读取,这是valgrind的旧版本还不了解的。所以升级你的valgrind,你会没事的。

不,应该永远不会有问题。如果第一个字节是可读的,那么最后一个字节也是可读的。对齐读取不能跨越页面边界。这是一个valgrind错误-请参阅我的答案。升级到最新的SVN版本可以纠正此问题。感谢您指出这个错误!:)您还记得这适用于哪个版本的valgrind吗?这也是最近gcc和valgrind的一个问题,并且不仅限于SSE,您可以在这里看到:
lenain@perseus:~/work/leaf$ valgrind ./leaf
==3409== Memcheck, a memory error detector
==3409== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3409== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==3409== Command: ./leaf
==3409== 
Step 1
strlen : 11
Step 2
==3409== Invalid read of size 8
==3409==    at 0x4EA3B92: __GI_strlen (strlen.S:31)
==3409==    by 0x40098A: main (in /home/lenain/work/leaf/leaf)
==3409==  Address 0x5189048 is 8 bytes inside a block of size 12 alloc'd
==3409==    at 0x4C234CB: calloc (vg_replace_malloc.c:418)
==3409==    by 0x4008F0: main (in /home/lenain/work/leaf/leaf)
==3409== 
strlen : 11
==3409== 
==3409== HEAP SUMMARY:
==3409==     in use at exit: 0 bytes in 0 blocks
==3409==   total heap usage: 1 allocs, 1 frees, 12 bytes allocated
==3409== 
==3409== All heap blocks were freed -- no leaks are possible
==3409== 
==3409== For counts of detected and suppressed errors, rerun with: -v
==3409== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)