使用std :: to_string()创建std :: String时的segfault

Segfault when creating a std::string with std::to_string()

本文关键字:std 创建 String segfault 时的 string to 使用      更新时间:2023-10-16

在Linux中,但Windows却没有以下位置获得segfault。我目前不知道本节有什么问题。我想将std ::字符串推入一个std ::向量,后来用于生成日志。以下位置的条目仅继承时间戳和一个perf柜台。

LogEntry lentry = {
  lentry.m_LogTime = get_time_stamp(),
  lentry.m_LogMsg = "txt: " + std::to_string(GetTickCount() - iBegin) // debugger complains here
};
m_Log.push_back(lentry);
/*
inline unsigned long long GetTickCount() {
  using namespace std::chrono;
  return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}
struct LogEntry {
  std::string m_LogTime;
  std::string m_LogMsg;
};
*/

GDB

(gdb) bt 25
#0  0x00007ffff2f39133 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) () from /usr/lib64/libstdc++.so.6
#1  0x00007ffff7f631a9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) ()
#2  0x00007ffff7cad5eb in xxx::zzz (this=0x7ffffffe44d0, data=..., iSelModel=2) at file.cpp:1110
(gdb) bt full
#0  0x00007ffff2f39133 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) () from /usr/lib64/libstdc++.so.6
No symbol table info available.
#1  0x00007ffff7f631a9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) ()
No symbol table info available.
#2  0x00007ffff7cad5eb in AbstractPoserEngine::ExportModel (this=0x7ffffffe44d0, data=..., iSelModel=2) at /home/cst/Desktop/PoserGUI/src/engine/AbstractPoserEngine.cpp:1110
        nDim = {259, 439, 667}
        aSkinMat = std::vector of length 1, capacity 1 = {34}
        iBegin = 13520825
        lentry = {m_LogTime = Traceback (most recent call last):
  File "/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py", line 558, in to_string
    return self.val['_M_dataplus']['_M_p'].lazy_string (length = len)
RuntimeError: Cannot access memory at address 0x3dc775
, m_LogMsg = Traceback (most recent call last):
  File "/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py", line 558, in to_string
    return self.val['_M_dataplus']['_M_p'].lazy_string (length = len)
RuntimeError: Cannot access memory at address 0x4247ae140000000f
}

将它们用作周围构造函数的参数时,您的变量是未初始化的。如果使用适当的警告标志编译,则应获取错误消息。因此,我的猜测是,某些std::string不变性在分配中被打破,这就是导致分割故障的原因。

例如

#include <iostream>
using std::cout;
using std::endl;
class Test {
public:
    Test() {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    Test(const Test&) {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    Test(Test&&) {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    Test& operator=(int) {
        cout << __PRETTY_FUNCTION__ << endl;
        return *this;
    }
};
class Something {
public:
    Something(Test test_in) : test{test_in} {}
    Test test;
};
int main() {
    Something something = Something{
        something.test = 2
    };
}

此代码的输出是

Test& Test::operator=(int)
Test::Test(const Test&)
Test::Test(const Test&)

您可以看到分配运算符首先调用,这违背了类对象在分配给阶级对象之前的初始化。您可以在此处看到此操作https://wandbox.org/permlink/hnyf9yaf3jtp13vf或http://coliru.stacked-crooked.com/a/cc7fe50840dd57ac8

进一步的编译器所有警告标志时,我的编译器给我以下错误

variable 'something' is uninitialized when used within its own initialization [-Werror,-Wuninitialized]

尝试将代码更改为此

LogEntry lentry = {
    get_time_stamp(), 
    "txt: " + std::to_string(GetTickCount() - iBegin)
};