g++误解了c++语义
g++ misunderstands c++ semantics
这个问题有两种可能的解决方案:我不理解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++引用),并知道何时调用构造函数、复制构造函数和析构函数。
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- Boost Spirit,获取迭代器内部语义动作
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 在C++17中,引用const字符串的语义应该是什么
- Xcode 语义问题引用或以前定义的代码
- 使用移动和复制语义时函数匹配如何工作?
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 移动语义和深层/浅层复制之间有什么关系?
- 了解构造函数在移动、复制、赋值语义中的行为
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 在C++中使用移动语义的正确方法是什么?
- C++ 价值语义、不可变性和继承性
- 移动语义 c++ 单链表