g ++误解了c ++语义

时间:2011-06-21 17:53:07

标签: c++ g++

这个问题有两种可能的解决方案:我不理解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需要一些修复,而问题不存在)?

3 个答案:

答案 0 :(得分:3)

首先,通过引用返回在堆上分配的内容是内存泄漏的确定方法,因此我绝不会建议实际执行此操作。

除非明确规定所有权语义,否则第二种情况仍可能导致泄密。您是否考虑使用智能指针而不是原始指针?

至于为什么它不起作用,它可能与所有权语义有关,而不是因为你通过引用返回,但我看不到发布代码中的问题。

答案 1 :(得分:1)

“我应该如何调试程序以找到这样一个可怕的错误?” 如果您使用的是Linux,请尝试在valgrind下运行 - 这应该可以进行任何内存涂鸦。

答案 2 :(得分:0)

你忽略了raw_input = 0x20,这显然是一个无效的指针。这是在segfault之后你在调试器中得到的有用信息。

对于此类普通问题,请学习使用Valgrind的memcheck,它会为您提供有关程序滥用内存的信息。

同时我建议你确保你理解按值传递vs传递引用(指针和C ++引用)并知道何时调用构造函数,复制构造函数和析构函数。