std :: vector <std :: string>崩溃

dim*_*mba 6 c++ debugging stl g++

这个问题是我的问题的延续.

这是有问题的代码.

啊:

#include <string>
#include <vector>

std::vector<std::string> foo();
Run Code Online (Sandbox Code Playgroud)

a.cpp

#include "a.h"

std::vector<std::string> foo()
{
   std::vector<std::string> v;
   return v;
}
Run Code Online (Sandbox Code Playgroud)

最后是main.cpp:

#include "a.h"
#include <iostream>

int main()
{
    std::vector<std::string> s = foo();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译如下(main.cpp用STL调试标志编译):

g++ -c a.cpp
g++ -D_GLIBCXX_DEBUG main.cpp a.o
Run Code Online (Sandbox Code Playgroud)

运行a.out时,进程崩溃:

Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x00007fe355998c43 in __gnu_debug::_Safe_iterator_base::_M_detach_single() () from /usr/lib64/libstdc++.so.6
(gdb) bt
#0  0x00007fe355998c43 in __gnu_debug::_Safe_iterator_base::_M_detach_single() () from /usr/lib64/libstdc++.so.6
#1  0x00007fe355999ebc in __gnu_debug::_Safe_sequence_base::_M_detach_all() () from /usr/lib64/libstdc++.so.6
#2  0x0000000000400cac in __gnu_debug::_Safe_sequence_base::~_Safe_sequence_base() ()
#3  0x0000000000400cc6 in __gnu_debug::_Safe_sequence<std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::~_Safe_sequence() ()
#4  0x0000000000400ce7 in std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~vector() ()
#5  0x0000000000400c35 in main ()
Run Code Online (Sandbox Code Playgroud)

我的gcc:

Using built-in specs.
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.4 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.4 --enable-linux-futex --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux
Thread model: posix
gcc version 4.4.1 [gcc-4_4-branch revision 150839] (SUSE Linux)
Run Code Online (Sandbox Code Playgroud)

bdo*_*lan 12

你的问题只是-D_GLIBCXX_DEBUG转移到了a.cpp.此标志向STL结构添加其他调试信息,因此其使用必须在项目中的所有文件中保持一致.否则,不同的文件不同意的内存布局std::vectorstd::string,导致不确定的行为(崩溃,你的情况).

  • 为了清楚起见,通常,应该一劳永逸地设置标志,并将其一致地应用于您希望编译的整个文件集. (2认同)

Bro*_*ses 1

在上一个问题中,您在此处引用了 GCC 文档:http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html。该文档指出 GCC libstdc++“支持每用户重新编译”,并将其定义如下:

每次使用重新编译:用户必须重新编译其应用程序的各个部分以及依赖于应进行调试的 C++ 库,以及与这些容器交互的任何其他代码。这意味着访问特定标准容器实例的一组翻译单元可以在发布模式(不检查)或调试模式(完全检查)下编译,但必须全部以相同的方式编译;没有看到标准容器实例的翻译单元不需要重新编译。这也意味着包含在发布模式下编译的特定实例化(例如 std::vector)的翻译单元 A 可以链接到包含在调试模式下编译的相同实例化的翻译单元 B(部分重新编译时不存在的功能) )。虽然这种行为在技术上违反了单一定义规则,但这种能力在实践中往往非常重要。libstdc++ 调试模式支持此级别的重新编译。

对于每单元编译,这就是您在这里尝试做的事情,它说:

我们相信,如果我们打算提供安全的迭代器、保持程序语义不变、并且在发布模式下不降低性能,那么这种级别的重新编译实际上是不可能的......

因此,我对你之前问题的回答并不完全准确,我深表歉意。我添加了一个附录来纠正它,我希望这是关于如何解决多库问题的有用建议。