为什么 std::basic_string<char> 在我的重载流运算符上出现段错误?

Why is std::basic_string<char> segfaulting on my overloaded stream operator?

我正在尝试编译 运行 这个看起来无害的 class 在 g++ 中,但程序在 malloc 或 memmove 上保持段错误。这里几乎没有任何事情发生。

我在使用 -g 编译并通过 gdb 运行编译时收到以下错误。这是我对如何调试它的了解程度。

出于某种原因,这只会在从两个单独的文件编译时出现段错误。如果我 copy/paste 一切都变成 main.cpp 它 运行 没问题。

Windows/Cygwin g++ (海湾合作委员会) 4.9.2:

Program received signal SIGSEGV, Segmentation fault.

0x61137eb5 in memmove () from /usr/bin/cygwin1.dll

..

Program received signal SIGSEGV, Segmentation fault.

0x610ef417 in muto::acquire(unsigned long) () from /usr/bin/cygwin1.dll

Windows/g++ 4.9.2-TDM:

Program received signal SIGSEGV, Segmentation fault.

0x777d27d0 in ntdll!RtlCompareMemoryUlong () from /c/Windows/SysWOW64/ntdll.dll

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7279ef5 in _int_malloc () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7_0.5.x86_64 libgcc-4.8.2-16.2.el7_0.x86_64 libstdc++-4.8.2-16.2.el7_0.x86_64 ..

CentOS 7/g++ (GCC) 4.8.2:

Program received signal SIGSEGV, Segmentation fault.

_int_malloc (av=0x7ffff75b6760 , bytes=29) at malloc.c:3281

3281 {

我正在使用以下标志进行编译:

-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused

我错过了什么?我还能在 gdb 中做些什么来帮助查明问题吗?

$ g++ main.cpp string_t.cpp -g -std=c++11 $DEBUG -o test.exe && ./test.exe

main.cpp

#include <iostream>

using std::cout;
using std::endl;

#include "string_t.h"

int main() {
   string_t a("test");

   cout << a << endl;

   return 0;
}

string_t.h

#include <cstdint>
#include <string>

class string_t {
std::basic_string<char> _base;

public:
   string_t(
      const char* s);

   friend std::ostream& operator<<(
      std::ostream& l,
      const string_t& r);
};

string_t.cpp

#include "string_t.h"

string_t::string_t(
   const char* s) :
   _base(s) {
}

std::ostream& operator<<(
   std::ostream& l,
   const string_t& r)
{
   l << r._base.c_str();

   return l;
}

您没有将 <ostream> 包含到第二个翻译单元 (string_t.cpp) 中,因此无法找到重载解析

template<class CharT, class Traits>
basic_ostream<CharT,Traits>& operator << (basic_ostream<CharT,Traits>& os, const char* s);

当你调用

l << r._base.c_str();

相反,string_t(const char* s)用作转换构造函数(未声明explicit)以创建新的string_t对象和

std::ostream& operator<<(std::ostream& l, const string_t& r)

被再次调用,所以你最终会无限递归。