这个问题有两种可能的解决方案:我不理解c ++语义或g ++。
我正在编写一个简单的网络游戏。我一直在构建游戏用于通过网络进行通信的库。指定了一个用于处理应用程序之间连接的类。另一个类实现服务器功能,因此它拥有方法accept()
。方法是返回Connection类。
有一些方法可以返回课程。我试过这三个:
Connection accept() {
...
return Connection(...);
}
Connection* accept() {
...
return new Connection(...);
}
Connection& accept() {
...
Connection *temp = new Connection(...);
return *temp;
}
这三个都被g ++接受了。问题是第三个是有点错误的。当您使用Connection类型的对象的内部信息时,您将失败。我不知道出了什么问题,因为对象中的所有字段看起来都是初始化的。我的问题是当我使用协议缓冲库中的任何函数时,我的程序被Segmentation fault终止。每次调用protobuf库时,下面的函数都会失败。
Annoucement Connection::receive() throw(EmptySocket) {
if(raw_input->GetErrno() != 0) throw EmptySocket();
CodedInputStream coded_input(raw_input);
google::protobuf::uint32 n;
coded_input.ReadVarint32(&n);
char *b;
int m;
coded_input.GetDirectBufferPointer((const void**)&b, &m);
Annoucement ann;
ann.ParseFromArray(b, n);
coded_input.Skip(n);
return ann;
}
我每次都这样:
程序接收信号SIGSEGV, 分段故障。 0x08062106 in 谷歌:: protobuf的:: IO :: ::的FileInputStream :: CopyingFileInputStream GetErrno (这= 0x20)at /usr/include/google/protobuf/io/zero_copy_stream_impl.h:104
当我将accept()
更改为第二个版本时,它完全有效(第一个也很好,但同时修改了概念)。
您是否遇到过与此类似的问题?为什么第三版accept()
错了?我应该如何调试程序以找到这样一个可怕的错误(我认为protobuf需要一些修复,而问题不存在)?
答案 0 :(得分:3)
首先,通过引用返回在堆上分配的内容是内存泄漏的确定方法,因此我绝不会建议实际执行此操作。
除非明确规定所有权语义,否则第二种情况仍可能导致泄密。您是否考虑使用智能指针而不是原始指针?
至于为什么它不起作用,它可能与所有权语义有关,而不是因为你通过引用返回,但我看不到发布代码中的问题。
答案 1 :(得分:1)
“我应该如何调试程序以找到这样一个可怕的错误?” 如果您使用的是Linux,请尝试在valgrind下运行 - 这应该可以进行任何内存涂鸦。
答案 2 :(得分:0)
你忽略了raw_input = 0x20,这显然是一个无效的指针。这是在segfault之后你在调试器中得到的有用信息。
对于此类普通问题,请学习使用Valgrind的memcheck,它会为您提供有关程序滥用内存的信息。
同时我建议你确保你理解按值传递vs传递引用(指针和C ++引用)并知道何时调用构造函数,复制构造函数和析构函数。