使用std :: to_string()

时间:2017-06-28 15:05:06

标签: c++

在Linux中,但不是Windows我在以下位置获得了SEGFAULT。我目前不知道这部分有什么问题。我想要的是将std :: string推入std :: vector,后者用于生成日志。以下位置的条目只是继承了时间戳和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
}

1 个答案:

答案 0 :(得分:1)

当您将变量用作周围构造函数的参数时,它们是未初始化的。如果使用适当的警告标志进行编译,则应收到错误消息。所以我的猜测是,在赋值中会破坏一些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/hnyF9YAf3JtP13vfhttp://coliru.stacked-crooked.com/a/cc7fe50840d57ac8

中查看此操作

此外,当编译器带有所有警告标志时,我的编译器会给我以下错误

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

尝试将代码更改为此

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