gpt4 book ai didi

c++ - 为什么我的 C++ 代码在使用 read(...) 函数后会导致段错误?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:05:28 24 4
gpt4 key购买 nike

我的应用程序在一行代码上挂起,这行代码似乎没有任何问题,但我的 IDE 似乎在该行挂起并出现错误:

gdb/mi (24/03/09 13:36) (Exited. Signal 'SIGSEGV' received. Description: Segmentation fault.)

这行代码只是调用了一个没有代码的方法。当您有空引用时,不是段错误吗?如果是这样,空方法怎么会有空引用?

这段代码,似乎是导致问题的原因:

#include <sys/socket.h>

#define BUFFER_SIZE 256

char *buffer;

buffer = (char*)GetSomePointer()->SomeStackMemoryString.c_str();
int writeResult = write(socketFD, buffer, BUFFER_SIZE);

bzero(buffer, BUFFER_SIZE);
int readResult = read(socketFD, buffer, BUFFER_SIZE);

当使用 read(...) 方法的行被注释掉时,问题就消失了。

更新:

我已将问题更改为指向实际问题,并且删除了所有不相关的代码 - 我还删除了 answered my own question为了让阅读这篇文章的人明确知道问题是什么,请在说“你是个白痴!”之前先阅读我的回答。

最佳答案

首先,通过空指针或引用调用方法严格来说是未定义的行为。但除非调用是虚拟的,否则它可能会成功。

如果引用/指针为空,则虚拟调用虚拟方法(通过指针/引用,而不是从具有 Class::Method() 调用方式的派生类)总是失败,因为虚拟调用需要访问 vtable 并访问 vtable通过空指针/引用是不可能的。所以你不能通过引用/指针调用一个空的虚方法。

要理解这一点,您需要更多地了解代码的组织方式。对于每个非内联方法,都有一段代码段包含实现该方法的机器代码。

当调用是非虚拟的(从派生类或通过引用/指针的非虚拟方法)完成时,编译器确切地知道要调用哪个方法(无多态性)。所以它只是插入对代码的确切部分的调用,并将 this 指针作为第一个参数传递给那里。如果通过空指针调用,this 也将为空,但您不关心您的方法是否为空。

当虚拟调用(通过引用/指针)完成时,编译器不知道要调用哪个方法,它只知道有一个虚方法表,表的地址存储在对象中。为了找到要调用的方法,有必要首先取消对指针/引用的引用,找到表,从中获取方法的地址,然后才调用该方法。读取表是在运行时完成的,而不是在编译期间。如果指针/引用为空,此时会出现段错误。

这也解释了为什么不能内联虚拟调用。编译器在编译期间查看源代码时根本不知道要内联什么代码。

关于c++ - 为什么我的 C++ 代码在使用 read(...) 函数后会导致段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/677444/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com