简体   繁体   English

析构函数分段故障链接列表

[英]Destructor Segmentation Fault Linked List

So, I've searched forums up and down and either haven't found anything that helps me or haven't found anything that makes enough sense to connect it to the problem I'm having. 因此,我在论坛上上下搜索,或者没有找到任何对我有帮助的东西,或者没有找到任何有意义的东西将其与我遇到的问题联系起来。 My program stores Points and holds these points inside a struct (LNode) which is pointed to by my Cluster class creating a linked list. 我的程序存储点并将这些点保存在结构(LNode)中,该结构由我的Cluster类创建链接列表所指向。 The only dynamic allocation is for the Lnodes and the value array of the Point objects. 唯一的动态分配是针对Lnodes和Point对象的值数组。 I am at a loss on what is causing my program to get a segmentation fault. 我对导致程序出现分段错误的原因不知所措。 I know from running the debugger that it happens when my function dynamically allocates a new LNode in the add function of my Cluster.cpp file. 通过运行调试器,我知道当我的函数在Cluster.cpp文件的add函数中动态分配新的LNode时,就会发生这种情况。 It happens when the function goes to exit and the point destructor is called. 它在函数退出并调用点析构函数时发生。 Here are the relevant parts of my files: 这是我文件的相关部分:

point.h

#include <iostream>

namespace Clustering {

class Point {
    unsigned int __id;
    int __dim;        // number of dimensions of the point
    double *__values; // values of the point's dimensions

    static unsigned int __idGen; // id generator

public:
    Point(int);
    Point(int, double *);

    // Big three: cpy ctor, overloaded operator=, dtor
    Point(const Point &);
    Point &operator=(const Point &);
    ~Point();

point.cpp 点cpp

#include "Point.h"
#include <cmath>
#include <assert.h>

using namespace std;
using namespace Clustering;

namespace Clustering {

unsigned int Point::__idGen = 0;

Clustering::Point::Point(int i)
{
    __dim = i;
    __values = new double[__dim];
    for (int count = 0; count < __dim; ++count)
        __values[count] = 0.0;
    __id = __idGen++;
}

Point::Point(int i, double *pDouble)
{
    __dim = i;
    __values = pDouble;
    __id = __idGen++;
}

Point::Point(const Point &point)
{
    __dim = point.__dim;
    __values = new double[__dim];
    for (int count = 0; count < __dim; ++count)
        __values[count] = point.__values[count];
    __id = point.__id;
}

Point &Point::operator=(const Point &point)
{
    if (this == &point)
        return *this;
    else {
        __dim = point.__dim;
        for (int count = 0; count < __dim; ++count)
            __values[count] = point.__values[count];
        __id = point.__id;
    }
    return *this;
}

Point::~Point()
{
    std::cout << "This is the value " << &__values << std::endl;
    delete  [] __values;
}

Cluster.h 集群

#include "Point.h"

namespace Clustering {

typedef struct LNode *LNodePtr;

struct LNode {

    Point point;
    LNodePtr next;
    LNode(const Point &p, LNodePtr n);

};

class Cluster {

    int __size;
    LNodePtr __points;

    //void __del();
    //void __cpy(LNodePtr pts);
    //bool __in(const Point &p) const;


public:
    Cluster();

    // The big three: cpy ctor, overloaded operator=, dtor
    Cluster(const Cluster &);
    Cluster &operator=(const Cluster &);
    ~Cluster();

    // Set functions: They allow calling c1.add(c2.remove(p));
    void add(const Point &);

    // Overloaded operators

    // Members: Subscript
    const Point &operator[](unsigned int index) const;

cluster.cpp cluster.cpp

#include <cstdlib>
#include <assert.h>
#include "Cluster.h"

namespace Clustering{

LNode::LNode(const Point &p, LNodePtr n = nullptr) : point(0) {
    point = p;
    next = n;
}

Cluster::Cluster() {
    __size = 0;
    __points = nullptr;
}

Cluster::Cluster(const Cluster &cluster) {
    __size = cluster.__size;
    if(__size == 0)
        __points = nullptr;
    else{
        for(int count = 0; count < cluster.__size; ++count){
            add(cluster[count]);
        }
    }
}

Cluster &Cluster::operator=(const Cluster &cluster) {
    if(this == &cluster)
        return *this;
    else {
        for(int count = 0; count < cluster.__size; ++count){
            add(cluster[count]);
        }
    }
    return *this;
}

Cluster::~Cluster(){
    if(__points != nullptr){
        LNodePtr currPtr = __points;
        LNodePtr nextPtr = nullptr;
        while(currPtr != nullptr){
            nextPtr = currPtr->next;
            delete currPtr;
            currPtr = nextPtr;
        }
    }
    else
        assert(__size==0);
}
void Cluster::add(const Point &point) {
    Point p(point);
    LNodePtr insertPtr = new LNode(p, nullptr);
    LNodePtr prev = __points;
    LNodePtr next = __points;
    if(__points == nullptr) {
        __points = insertPtr;
        __size++;
    }
    else if(__points->next == nullptr){
         if (point < __points->point) {
            __points = insertPtr;
            __size++;
        }
        else
            __points->next = insertPtr;
    }
    else{
        while(next != nullptr && (prev->point < point && point >= next->point)){
            prev = next;
            next = next->next;
        }
        prev->next = insertPtr;
    }
}
 const Point &Cluster::operator[](unsigned int index) const {
    assert(__points != nullptr && index < __size);
    LNodePtr cursor = __points;
    for(int count = 0; count < index; ++count)
        cursor = cursor->next;
    return cursor->point;
}

and in main, a simple test like this is what I use. 总的来说,我使用的是一个简单的测试。

Cluster c1;
c1.add(Point(5));

Any help is greatly appreciated, I am fairly new to this type of structure and have been dealing with this error for a solid part of 2 days now. 非常感谢您的帮助,对于这种类型的结构我还是很陌生,并且已经处理此错误已有2天了。

In the Cluster::add function you create a new LNode and in the LNode constructor the point object is constructed with a zero sized array. Cluster::add函数中,您将创建一个新的LNode并在LNode构造函数中,使用零大小的数组构造该point对象。 Which is allowed but gives undefined behavior. 这是允许的,但给出未定义的行为。 See C++ new int[0] -- will it allocate memory? 参见C ++ new int [0]-它会分配内存吗? . You have created a zero sized array, but in the Point::operator= function, which is used in the first line of the LNode constructor, you never allocate new memory for __values so you are copying 5 values into a zero sized array. 您已经创建了一个零大小的数组,但是在LNode构造函数的第一行中使用的Point::operator=函数中,您从未为__values分配新的内存,因此您将5个值复制到一个零大小的数组中。 Who knows what you're overwriting when that happens. 谁知道发生这种情况时您将覆盖什么。 Try running with valgrind or some other memory analysis tool. 尝试使用valgrind或其他内存分析工具运行。 That should identify this problem and any others. 那应该确定这个问题和其他任何问题。

Michael covered the segmentation violation problem; 迈克尔介绍了细分违规问题; there is a smaller, logical problem in the add() method: the method never updates insertptr->next, so wherever the new node is inserted, all following already existing nodes are lost. add()方法中存在一个较小的逻辑问题:该方法从不更新insertptr-> next,因此,无论在哪里插入新节点,所有后面已有的节点都会丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM