Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用std::string::iterator的Linux分段错误_C++_String_Sockets_Iterator_Segmentation Fault - Fatal编程技术网

C++ 使用std::string::iterator的Linux分段错误

C++ 使用std::string::iterator的Linux分段错误,c++,string,sockets,iterator,segmentation-fault,C++,String,Sockets,Iterator,Segmentation Fault,我在CentOS 6.4 64位机器上的libc.so.6中不断遇到异常的分段错误。这是gdb最常报告的回溯: 0x00007ffff60d9b3f in memcpy () from /lib64/libc.so.6 (gdb) backtrace #0 0x00007ffff60d9b3f in memcpy () from /lib64/libc.so.6 #1 0x00000000004b6a6b in std::string::_S_construct<__gnu_cxx::

我在CentOS 6.4 64位机器上的libc.so.6中不断遇到异常的分段错误。这是gdb最常报告的回溯:

0x00007ffff60d9b3f in memcpy () from /lib64/libc.so.6
(gdb) backtrace
#0  0x00007ffff60d9b3f in memcpy () from /lib64/libc.so.6
#1  0x00000000004b6a6b in std::string::_S_construct<__gnu_cxx::__normal_iterator<char*, std::string> > ()
#2  0x00000000004b719b in NewsMAIL::SMTPClient::receiveLine(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*) ()
#3  0x00000000004b776f in NewsMAIL::SMTPClient::handleResponse() ()
有时它100%工作,没有任何失败,所以不幸的是,并非每次都如此。 上面的代码是对此的稍微修改版本:

有没有人想过为什么会发生这种情况?我正在使用g++4.7.2进行编译

谢谢

Nate使用静态变量(缓冲区)不是线程安全的。可能导致撞车

您应该添加一个检查,确保
不是


顺便说一句,行
Buffer=std::string(“”)可以是
Buffer.clear()

除了静态变量问题外,您确定接收的数据不包含嵌入的空字符吗

如果生成的缓冲区包含嵌入的空字节,此行将不会使用+=运算符进行正确的连接:

Buffer += Bucket;
+=重载假定Bucket是一个c样式的字符串,因此在发生连接时,遇到的第一个空字节将用作终止符

看一看代码,似乎是这样的:如果Bucket确实包含嵌入的NULL chracter,那么执行上述连接可能会导致“iter”迭代器指向缓冲区的end()(在while()循环之后的那些行中)

相反,您可以这样做:

Buffer.append(Bucket, BytesRecv)
这保证了Bucket正在寻址的所有字符都将连接到现有字符串上


但在做出任何更改之前,请确保您确切地知道问题是什么,特别是因为您声明错误并不经常发生。在不知道错误的真正原因的情况下更改代码可能只是掩盖错误,从而使诊断真正问题变得更加困难。

尽管应用程序是多线程的,但每个线程都有自己的此类实例,因此静态std::string决不会跨越线程边界。不过,我确实将其更改为Buffer.clear()-感谢您的建议。这是您的错误-静态变量。2个线程不能同时调用此函数。它们都操作相同的对象(缓冲区)。你应该用一个关键部分来保护这个函数。Egur我觉得自己像个白痴,谢谢你弄明白了这一点-它现在工作得完美无缺:)没问题。这是一个常见的错误。谢谢Paul的建议,有没有关于在没有静态缓冲区的情况下接收而不是逐字节进行的建议?或者我只是过分担心逐字节的效率真的很低?好吧,您可以将缓冲区设置为SMTPClient类的非静态成员——这将确保缓冲区不会相互碰撞。然而,在最后,如果这是您的目标,您需要弄清楚如何将多个缓冲区合并到单个缓冲区中。除了您的两个答案之外,字符串的
运算符+=
可以使任何迭代器无效。想象一下,如果字符串的内部缓冲区需要调整大小,就会发生这种情况。
Buffer.append(Bucket, BytesRecv)