【问题标题】:std::wstring::find() broken in g++?std::wstring::find() 在 g++ 中损坏?
【发布时间】:2020-12-24 16:55:49
【问题描述】:

这个程序有什么问题:

#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

【问题讨论】:

  • 请注意,当我将字符串的大小减少一个字符时: -- 缩短字符数可能会调用 string 的短字符串优化类,因此不会分配内存。 Here is more information
  • 我用 g++ 10.2 和 valgrind 3.16 进行了测试,。它没有显示错误。所以可能是由于旧版本的 g++ 或 valgrind 上的错误。
  • @Jaebum 感谢您的提示。我在我的 Ubuntu 18 上构建了 Valgrind 3.16.1。该版本的 Valgrind 没有报告错误。您能否将您的消息发布为答案,以便我接受?

标签: c++ g++ valgrind wstring


【解决方案1】:

可能是 valgrind 方面的错误。我用 g++ 10.2 和 valgrind 3.16 进行了测试,没有错误。

【讨论】:

  • 我在我的 Ubuntu 18 上构建了 Valgrind 3.16.1。该版本的 Valgrind 没有报告错误(g++ 版本不变)。
【解决方案2】:

不是真正的错误,但旧的 Valgrind 版本可能不知道 sse 字符串操作。

作为一种优化,str* 和 mem* 函数可以执行 8 字节读取,因为内存将始终以 8 字节增量分配。所以这可能会超出字符串的末尾,但它永远不会读取未分配的内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多