【问题标题】:Segmentation fault when calling destructor调用析构函数时出现分段错误
【发布时间】:2020-11-25 16:10:30
【问题描述】:

大家好,我是 C++ 新手,这是我的学期项目。当我在堆栈上创建 IPADDRESS 对象时,main.cpp 文件将运行,直到为 IPADDRESS 对象调用解构器成员。第一部分运行良好,第二部分返回相同的输出,只是有分段错误。

// Main file
#include <bits/stdc++.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include "IPInfo.h"

using namespace std;

// Function declaration of display()
void displayInfo(IPADDRESS);

int main(){

    const char* address = "cbc.ca";
    const char* command = "nslookup ";

        char buf[256];
        strcpy(buf, command);
        strcat(buf, address);

        string* Info = new(nothrow) string[256]; // Allocate 256 bytes to this string
        *Info = system(buf); // Allocate the response from the command line to Info (which is on the heap)
    cout << Info << endl << *Info << endl << "===============================" << endl << endl;
    delete[] Info;

    IPADDRESS test("cbc.ca");

    displayInfo(test);

// Displays but never exits the program correctly

    return 0;
}
void displayInfo(IPADDRESS Website){

    string* displayBus;
    displayBus = Website.getInfo();
    cout << displayBus;
}
// Header file
#ifndef IPInfo_H
#define IPInfo_H

#include <bits/stdc++.h>
#include <string>
#include <iostream>

using namespace std;
class IPADDRESS{
private:
    const char* command = "nslookup ";
    string url;
    string info;
    string address;
    int searchFor(string locator); // Find a substring in the getInfo string

public:
    string* getInfo(); // Using the system("nslookup") call, get the info (Will be allocated to heap)
    IPADDRESS(string website);
    ~IPADDRESS();
    string getIPAddress(); // Using searchFor() get rid of unneeded characters and dump the IPAddress to a string
    string getName(); // Also output the name

};

IPADDRESS::IPADDRESS(string website){
    url = website;
}

IPADDRESS::~IPADDRESS(){
}
#endif

【问题讨论】:

  • 请研究自动分配和动态分配之间最基本的区别,除了ALL_CAPS中的宏名称之外不要提供任何东西(也不要使用宏;-))
  • delete 表达式只能用于对应的new 表达式的结果。没有初始化&amp;address&amp;url&amp;infocommandnew 表达式,因此它们都不应该在delete 表达式中使用。因此,您的析构函数的行为是未定义的。
  • 您不应更改与此问题相关的原始代码。现在您编辑的代码不适合原始问题。您应该先发布所有内容,然后给出的答案将概述您在析构函数中所犯的错误,以及您在其余代码中所犯的其他错误。
  • 我现在知道了,正如我之前所说,我是这个社区的新手,非常感谢。

标签: c++ segmentation-fault destructor


【解决方案1】:

这是不对的

IPADDRESS::~IPADDRESS(){

    delete &address;
    delete &url;
    delete &info;
    delete command;
}

你不能也不应该delete任何你没有new的变量。

这里默认的编译器生成的析构函数就足够了,而且是正确的(完全可以去掉,在这种情况下会隐式生成)。

~IPADDRESS() = default;  // don't even need this, compiler will generate in this case

【讨论】:

  • 为什么要显式默认析构函数?这里没有被压制,隐式生成的就是正确的。
  • @cigien 好点,我更新了我的答案以更清楚地指出这一点。
  • 感谢大家的快速回复!
  • 我放入了正确的析构函数,但我仍然遇到分段错误。知道那可能是什么吗?
  • @UbuntuUser 使用minimal reproducible example 更新您的原始帖子,而不仅仅是课程。无论如何,析构函数现在是正确的。除了默认值,它不应该做任何事情。
【解决方案2】:

delete 用于释放通过new 分配的内容,否则不得使用它。

目前您发布的代码不包含new,因此析构函数应该是:

IPADDRESS::~IPADDRESS(){
}

另外请注意,如果您使用动态内存分配,您应该遵循The Rule of Three。 最好避免在 C++ 中进行裸动态内存分配。

【讨论】:

  • 应该省略析构函数,因为生成的默认析构函数是正确的。
  • 为什么要定义析构函数?最好默认它,更好的是使用隐式。
猜你喜欢
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多