g++误解了c++语义

g++ misunderstands c++ semantics

本文关键字:语义 c++ 误解 g++      更新时间:2023-10-16

这个问题有两种可能的解决方案:我不理解c++语义,或者g++理解。

我现在正在编写一个简单的网络游戏。我一直在建造一个游戏库,用来通过网络进行通信。有一个类被指定用于处理应用程序之间的连接。另一个类实现服务器功能,因此它拥有一个方法accept()。方法是返回一个Connection类。

有几种方法可以返回类。我试过这三种:

Connection accept() {
...
return Connection(...);
}
Connection* accept() {
...
return new Connection(...);
}
Connection& accept() {
...
Connection *temp = new Connection(...);
return *temp;
}

这三个都被g++接受了。问题是第三个有点错误。当您使用Connection类型的对象的内部信息时,您将失败。我不知道出了什么问题,因为对象中的所有字段看起来都是初始化的。我的问题是,当我使用协议缓冲库中的任何函数时,我的程序都会因分段故障而终止。下面的函数每次调用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英寸google::protobuf::io::FileInputStream::CopyingFileInputStream::GetErrno(this=0x20)在/usr/include/google/protobuf/io/zero_copy_stream_impl.h:104

当我把accept()改成第二个版本时,它终于奏效了(第一个版本也不错,但我同时修改了概念)。

你遇到过与这个类似的问题吗?为什么accept()的第三个版本是错误的?我应该如何调试程序以发现如此可怕的错误(我认为protobuf需要一些修复,而问题并不存在)?

首先,通过引用返回堆上分配的东西肯定会导致内存泄漏,所以我从不建议实际这样做。

第二种情况仍然可能导致泄漏,除非所有权语义得到很好的指定。您是否考虑过使用智能指针而不是原始指针?

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

"我应该如何调试程序以发现如此可怕的错误?"如果你在Linux上,试着在valgrind下运行-这应该会拾取正在进行的任何内存涂鸦。

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

对于这种类型的一般问题,请学习使用Valgrind的memcheck,它会向您提供有关程序在哪里滥用内存的信息。

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