You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++程序出现Segmentation Fault及delete未分配对象错误排查求助

问题:point3D相关逻辑触发Segmentation Fault及释放未分配对象错误

开发一个测试4种方法的C++程序时,发现point3D相关逻辑引发Segmentation Fault,无法定位根源。已修复point3D的析构函数,但问题仍存在,运行时出现错误:

‘void operator delete(void*, std::size_t)’ called on unallocated object ‘p13D’

相关代码

//You only need iostream, no other header files are allowed
#include <iostream>
using namespace std;

//Code for part 1
class point2D {
    int x, y;
      char* label;
public:
    int getX(){
      return x;
    }
    int getY(){
      return y;
    }
   char* getLabel(){
      return label;
    }
    void setX(int a){
      x = a;
    }
    void setY(int b){
      y = b;
    }
    void setLabel(char* g){
      label = g;
    }
    virtual void show(){
      cout << "The point data is " << "(" << x << "," << y << "," << label << ")" << endl;
    }
    point2D(int x, int y, char * label){
      this->x = x;
      this->y = y;
      label = nullptr;
      setLabel(label);
    };
    ~point2D(){
      if(label != nullptr){
        delete[] label;
      }
    };

};

//Code for part 2
class point3D : public point2D {
protected:
  int z;
public:

  int getZ(){
    return z;
  }
  void setZ(int c){
    z = c;
  }
  void show(){
    cout << "(" << getX() << "," << getY() << "," << z << "," << getLabel() << ")\n";
  };
  point3D(int a, int b, int c, char * l) : point2D(a,b,l) {
      z = c;
  };
  ~point3D();
  
};
/*
//Code for Part 3
class node {
public:
  point3D* data;
  node* next;
  static int counter;
  void show(){
    if(data != nullptr){
      data->show();
    }
  }
  node(){
    data = nullptr;
    next = nullptr;
  }
  ~node(){
    if(data != nullptr){
      delete[] data;
    }
  }
};

//Code for Part 4
class linkedList {
    node* head;
public:
  bool empty() {
        return head == nullptr;
    }
    int size() {
        int c = 0;
        node* it = head;
        while (it != nullptr) {
            c++;
            it = it->next;
        }
        return c;
    }
    bool push(point3D* np) {
        node* nn = new node();
        nn->data = np;
        return push(nn);
    }
    bool push(node* nn) {
        nn->next = head;
        head = nn;
        return true;
    }
    bool append(point3D* np) {
        node* nn = new node();
        nn->data = np;
        return append(nn);
    }
    bool append(node* nn) {
        if (head != nullptr) {
            node* it = head;
            while (it->next != nullptr) {
                it = it->next;
            }
            it->next = nn;
        }
        else {
            head = nn;
        }
        return true;
    }
    void show() {
        node* it = head;
        while (it != nullptr) {
            it->show();
            it = it->next;
        }
    }
    linkedList() {
        head = nullptr;
    }
  ~linkedList(){
    node * it = head;
    node = nullptr;
    while(it != nullptr){
      
    }
  }
};

int node::counter = 0;
*/
int main() {
    int testMode;//Determines the test to be executed
    std::cin >> testMode;
    switch (testMode) {
    case 1:{
        //1) Test part 1
        point2D * p12D = new point2D(12, 24, (char*)"test 1");
        p12D->setX(25);
        p12D->setLabel((char*)"Landing Zone A");
        p12D->show();
        delete p12D;
        break;
    }
   case 2: {
        //2) Test part 2
        point3D* p13D = new point3D(12, 24, 36,(char*) "test 2");
        p13D->setY(50);
        p13D->setLabel((char*)"Landing Zone B");
        p13D->show();
        point2D* p22D = dynamic_cast<point2D*>(p13D);
        p22D->show();
        std::decay_t(&p13D);
        break;
    }
    /*
    case 3: {
        //3) Test part 3
        node* nn = new node();
        std::cout << node::counter << std::endl;
        delete nn;

        nn = new node();
        std::cout << node::counter << std::endl;
        point3D* p23D = new point3D(48,60,72,"Landing Zone C");
        nn->data = p23D;
        nn->show();
        
        delete nn;

        break;
    }
    case 4: {
        //4) Test part 4
        linkedList* myList = new linkedList();
        int i;
        for (i = 0; i < 3; i++) {
            node* nn = new node();
            point3D* p3D = new point3D(12*i, 24*i, 36*i, "Landing Zone ");
            myList->addNode(p3D);
        }
        myList->show();

        point3D* p3D = new point3D(12 * i, 24 * i, 36 * i, "Landing Zone ");
        myList->insertNode(p3D, 1);
        myList->show();
        delete myList;
        break;
    }
    */
    }
    return 0;
    
}

核心问题与修复方案

1. 基类析构函数未声明为虚函数

point2D的析构函数未标记为virtual,当通过基类指针操作派生类对象时,无法正确调用派生类析构函数,导致未定义行为。这是继承体系下的致命错误。

修复:

virtual ~point2D(){
  if(label != nullptr){
    delete[] label;
  }
};

2. Label指针内存管理错误

  • 构造函数中直接将常量字符串赋值给label,析构函数却用delete[]释放常量字符串(常量字符串并非堆内存分配),触发未定义行为。
  • setLabel方法直接赋值指针,未做内存拷贝,可能导致多个对象指向同一块内存,或释放非堆内存。

修复(在仅使用iostream的限制下,手动实现字符串拷贝):

void setLabel(const char* g){
  if(label != nullptr){
    delete[] label;
    label = nullptr;
  }
  if(g != nullptr){
    // 计算字符串长度
    int len = 0;
    while(g[len] != '\0') len++;
    label = new char[len + 1];
    // 拷贝字符串
    for(int i=0; i<=len; i++){
      label[i] = g[i];
    }
  }
}

// 修正构造函数
point2D(int x, int y, const char * label){
  this->x = x;
  this->y = y;
  this->label = nullptr;
  setLabel(label);
};

3. point3D析构函数未定义

代码中仅声明了~point3D();但未提供实现,会导致链接错误或运行时异常。需补充定义:

~point3D() = default;
// 或显式实现
~point3D() {
  // 基类虚析构会自动处理label,无需额外操作
}

4. 无效代码清理

test case 2中的std::decay_t(&p13D);无实际功能,属于无效代码,直接删除即可。

5. Node类析构错误(若启用Part3)

Node析构函数中用delete[] data;释放单个point3D对象指针,应改为delete data;:

~node(){
  if(data != nullptr){
    delete data;
  }
}

6. LinkedList析构函数未正确清理

LinkedList析构函数为空循环,未释放节点内存,导致内存泄漏。修复:

~linkedList(){
  node * it = head;
  while(it != nullptr){
    node* next = it->next;
    delete it;
    it = next;
  }
  head = nullptr;
}

内容的提问来源于stack exchange,提问作者CallMeAri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:54:56