std::wstring::find() 在 g++ 中损坏了吗?
std::wstring::find() broken in g++?
这个程序有什么问题:
#include <string>
int main()
{
std::wstring s = L"12345";
s.find(L"x");
return 0;
}
如果没有问题,Valgrind 为什么会抱怨:
$ g++ -g main.cpp
$ valgrind ./a.out
==9301== Memcheck, a memory error detector
==9301== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9301== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9301== Command: ./a.out
==9301==
==9301== Conditional jump or move depends on uninitialised value(s)
==9301== at 0x54AD3C1: __wmemchr_sse2 (memchr.S:254)
==9301== by 0x4F7667A: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::find(wchar_t const*, unsigned long, unsigned long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==9301== by 0x108A28: main (main.cpp:5)
==9301==
==9301==
==9301== HEAP SUMMARY:
==9301== in use at exit: 0 bytes in 0 blocks
==9301== total heap usage: 2 allocs, 2 frees, 72,728 bytes allocated
==9301==
==9301== All heap blocks were freed -- no leaks are possible
==9301==
==9301== For counts of detected and suppressed errors, rerun with: -v
==9301== Use --track-origins=yes to see where uninitialised values come from
==9301== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
请注意,当我将字符串的大小减少一个字符时:
#include <string>
int main()
{
std::wstring s = L"1234"; // string is shorter by one character
s.find(L"x");
return 0;
}
或者当我搜索字符串中的字符时:
#include <string>
int main()
{
std::wstring s = L"12345";
s.find(L"5"); // '5' is in the string
return 0;
}
或者当我使用 std::string
而不是 std::wstring
时:
#include <string>
int main()
{
std::string s = "12345"; // std::string instead of std::wstring
s.find("x");
return 0;
}
那么 Valgrind 就不会抱怨了。
我的环境:
$ uname -a
Linux dave-VirtualBox 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ g++ --version
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ valgrind --version
valgrind-3.13.0
不是真正的错误,但旧的 Valgrind 版本可能不知道 sse 字符串操作。
作为优化,str* 和 mem* 函数可以执行 8 字节读取,因为内存将始终以 8 字节增量分配。所以这可能会读取超出字符串末尾的内容,但它永远不会读取未分配的内存。
可能是 valgrind 方面的错误。我用 g++ 10.2 和 valgrind 3.16 测试过,它没有错误。
这个程序有什么问题:
#include <string>
int main()
{
std::wstring s = L"12345";
s.find(L"x");
return 0;
}
如果没有问题,Valgrind 为什么会抱怨:
$ g++ -g main.cpp
$ valgrind ./a.out
==9301== Memcheck, a memory error detector
==9301== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9301== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9301== Command: ./a.out
==9301==
==9301== Conditional jump or move depends on uninitialised value(s)
==9301== at 0x54AD3C1: __wmemchr_sse2 (memchr.S:254)
==9301== by 0x4F7667A: std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::find(wchar_t const*, unsigned long, unsigned long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==9301== by 0x108A28: main (main.cpp:5)
==9301==
==9301==
==9301== HEAP SUMMARY:
==9301== in use at exit: 0 bytes in 0 blocks
==9301== total heap usage: 2 allocs, 2 frees, 72,728 bytes allocated
==9301==
==9301== All heap blocks were freed -- no leaks are possible
==9301==
==9301== For counts of detected and suppressed errors, rerun with: -v
==9301== Use --track-origins=yes to see where uninitialised values come from
==9301== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
请注意,当我将字符串的大小减少一个字符时:
#include <string>
int main()
{
std::wstring s = L"1234"; // string is shorter by one character
s.find(L"x");
return 0;
}
或者当我搜索字符串中的字符时:
#include <string>
int main()
{
std::wstring s = L"12345";
s.find(L"5"); // '5' is in the string
return 0;
}
或者当我使用 std::string
而不是 std::wstring
时:
#include <string>
int main()
{
std::string s = "12345"; // std::string instead of std::wstring
s.find("x");
return 0;
}
那么 Valgrind 就不会抱怨了。
我的环境:
$ uname -a
Linux dave-VirtualBox 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ g++ --version
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ valgrind --version
valgrind-3.13.0
不是真正的错误,但旧的 Valgrind 版本可能不知道 sse 字符串操作。
作为优化,str* 和 mem* 函数可以执行 8 字节读取,因为内存将始终以 8 字节增量分配。所以这可能会读取超出字符串末尾的内容,但它永远不会读取未分配的内存。
可能是 valgrind 方面的错误。我用 g++ 10.2 和 valgrind 3.16 测试过,它没有错误。