的无效读我无法弄清楚为什么Valgrind的使用wchar_t
时打印Invalid read of size 8
。我正在运行一个带有valgrind-3.7.0和gcc 4.7.2的64位Ubuntu(3.5.0-25)系统。wchar_t的Valgrind的问题 - 大小8
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// const wchar_t *text = L"This is a t"; // no Valgrind error
// const wchar_t *text = L"This is a teeeeeeee"; // no Valgrind error
const wchar_t *text = L"This is a test"; // Valgrind ERRROR
wchar_t *new_text = NULL;
new_text = (wchar_t*) malloc((wcslen(text) + 1) * sizeof(wchar_t));
wcsncpy(new_text, text, wcslen(text));
new_text[wcslen(text)] = L'\0';
printf("new_text: %ls\n", new_text);
free(new_text);
return 0;
}
编译:
$ gcc -g -std=c99 test.c -o test
$ valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes ./test
Valgrind的结果:
==19495== Memcheck, a memory error detector
==19495== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19495== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19495== Command: ./test
==19495==
==19495== Invalid read of size 8
==19495== at 0x4ED45A7: wcslen (wcslen.S:55)
==19495== by 0x4ED5C0E: wcsrtombs (wcsrtombs.c:74)
==19495== by 0x4E7D160: vfprintf (vfprintf.c:1630)
==19495== by 0x4E858D8: printf (printf.c:35)
==19495== by 0x4006CC: main (test.c:16)
==19495== Address 0x51f1078 is 56 bytes inside a block of size 60 alloc'd
==19495== at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19495== by 0x40066F: main (test.c:12)
==19495==
new_text: This is a test
==19495==
==19495== HEAP SUMMARY:
==19495== in use at exit: 0 bytes in 0 blocks
==19495== total heap usage: 1 allocs, 1 frees, 60 bytes allocated
==19495==
==19495== All heap blocks were freed -- no leaks are possible
==19495==
==19495== For counts of detected and suppressed errors, rerun with: -v
==19495== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
现在,如果我跑相同,但有一个 '工作串',让我们说
const wchar_t *text = L"This is a t"; // no Valgrind error
// const wchar_t *text = L"This is a teeeeeeee"; // no Valgrind error
// const wchar_t *text = L"This is a test"; // Valgrind ERRROR
我没有问题:
==19571== Memcheck, a memory error detector
==19571== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19571== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19571== Command: ./test
==19571==
new_text: This is a t
==19571==
==19571== HEAP SUMMARY:
==19571== in use at exit: 0 bytes in 0 blocks
==19571== total heap usage: 1 allocs, 1 frees, 48 bytes allocated
==19571==
==19571== All heap blocks were freed -- no leaks are possible
==19571==
==19571== For counts of detected and suppressed errors, rerun with: -v
==19571== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
起初我还以为字符串大小应该始终是多个的8(也许有些WCS读的8块),但某些情况下失败了,那么我想我不得不追加总是8个字节为NULL结束((wcslen(item) + 2) * sizeof(wchar_t))
,它的工作,但不会使任何意义,因为sizeof(wchar_t)
- 在我的系统 - 为4个字节,应足以应付L'\0'
终止。
我也看了glibc的wcslen
源代码,但不是什么新鲜事。我现在正在考虑Valgrind问题。你们可以在这里扔一些光吗?是否值得向Valgrind提交错误?
谢谢
也许随着Valgrind的一个问题,是的。使用您的代码和相同的gcc版本,我无法获得版本3.8.1的错误。 – teppic 2013-03-22 14:48:14
更改此'NEW_TEXT =(wchar_t的*)malloc的((wcslen(文本)+ 1)*的sizeof(wchar_t的));'成为'NEW_TEXT =释放calloc(wcslen(文本)+ 1,的sizeof(* NEW_TEXT));'并重新测试。 – alk 2013-03-22 14:59:13
请注意 - 如果您在字符串中使用_any_非ASCII字符,您的代码将无法使用。你应该设置语言环境。 – teppic 2013-03-22 15:17:23