【问题标题】:Program crashes while freeing dynamically allocated memory释放动态分配的内存时程序崩溃
【发布时间】:2015-02-22 21:56:15
【问题描述】:

我在这里使用邻接表来表示一个图。

代码如下:

// A program to check the reachability between two nodes within a specified number of steps using an adjacency list
/***************************************************************************/

#include <iostream>
#include <fstream>

using namespace std;

struct node {
    int value;
    node* next;

    // Constructors:
    node() {
        value = 0;
        next = 0;
    }
    node(int x) {
        value = x;
        next = 0;
    }
};


node* al; // Adjacency list
int n; // Number of nodes
int node1, node2, k; // For reading input from the console
int counter;

bool checkReachability(int, int, int);
void freeMemory();

int main() {

    ifstream in;
    in.open("Input.txt");
    if(in) {
        in >> n;
        al = new node[n];
        for (int i = 0; i < n; i++) {
            al[i].value = i+1;
        }

        int a, b;
        while(in >> a >> b) {
            node* temp = &al[a-1];
            while(temp->next != 0) {
                temp = temp->next;
            }
            temp->next = new node(b);    
        }

        cout << "\n\nThe adjacency list representation of the graph is as follows: \n";
        cout << "________________________________\n\n";
        for (int i = 0; i < n; i++) {
            cout << al[i].value;
            node* temp = al[i].next;
            while(temp != 0) {
                cout << "->" << temp->value;
                temp = temp->next;
            }
            cout << endl;
        }
        cout << "________________________________\n";
        in.close();
        char c;
        do {
            cout << "\nPlease enter the input (node1, node2, k): \n";
            cin >> node1 >> node2 >> k;
            counter = 0;
            if (checkReachability(node1 - 1, node2, k)) {
                cout << "\nReachable within " << k << " steps";
                if (counter < k) {
                    cout << " (actually " << counter << ")";
                }
                cout << endl << endl;
            }
            else {
                cout << "\nNot reachable within " << k << " steps  \n";
            }
            cout << "\nDo you want to continue? Y/N \n\n";
            cin >> c;
        } while (c == 'Y' || c == 'y');
        freeMemory();
    } else {
        cout << "\nCouldn't find the input file\n\n";
    }
    return 0;
}

bool checkReachability(int n1, int n2, int k) {
    if ((n1 + 1) == n2) return true;
    counter++;
    if (counter <= k) {
        node* temp = &(al[n1]);
        while (temp != 0) {
            if (temp->value == n2) return true;
            temp = temp->next;
        }
        temp = al[n1].next; 
        while (temp != 0) {
            if (checkReachability(((temp->value)-1),n2,k)) return true;
            counter--;
            temp = temp->next;
        }   
    }
    return false;
}

void freeMemory() {
    cout << "\nFreeing memory...\n";
    // To free the dynamically allocated memory on the heap
    for (int i = 0; i < n; i++) {
        node* temp = &al[i];
        while(temp != 0) {
            node* temp2 = temp;
            temp = temp->next;
            delete temp2;
        }
    }
    //delete [] al;
    cout << "\nMemory freed.\n";
}

程序运行良好。只有当我选择退出它时,它才会调用它崩溃的 freeMemory 函数。请帮我找出问题所在。

Input.txt 文件:

5
1 2
2 5
3 4
1 3

输出:

The adjacency list represent
____________________________

1->2->3
2->5
3->4
4
5
____________________________

Please enter the input (node
1 2 1

Reachable within 1 steps


Do you want to continue? Y/N

y

Please enter the input (node
2 4 4

Not reachable within 4 steps

Do you want to continue? Y/N

N

Freeing memory...

然后,它崩溃了。

【问题讨论】:

  • 双重delete 我怀疑。另请参阅:stackoverflow.com/questions/28649952/…
  • 也可以粘贴输入文件内容,最好是可以重现您的问题的合理内容。请添加到问题中。包含崩溃的输出也不会不受欢迎。
  • @WhozCraig:好的,刚刚添加了 Input.txt 文件。
  • 我怀疑您的清理循环是 delete 数组中的初始条目,它是 not 动态分配的。只有通过next 链接 的条目与new 独立分配。 a[] 的初始持有是向量分配。我会在那里检查。
  • 也添加了输出。

标签: c++


【解决方案1】:

这是错误的:

void freeMemory() {
    cout << "\nFreeing memory...\n";
    // To free the dynamically allocated memory on the heap
    for (int i = 0; i < n; i++) {
        node* temp = &al[i]; // HERE
        while(temp != 0) {
            node* temp2 = temp;
            temp = temp->next;
            delete temp2;
        }
    }
    delete [] al;
    cout << "\nMemory freed.\n";
}

初始向量a1是通过new node[n]分配的。这意味着所有插槽a1[0...n-1] 中的初始条目是向量分配的一部分;不是此后与每个节点关联的链式邻接序列的一部分。我相信你需要这样做:

void freeMemory() {
    cout << "\nFreeing memory...\n";
    // To free the dynamically allocated memory on the heap
    for (int i = 0; i < n; i++) {
        node* temp = al[i].next; // start with next pointer
        while(temp != 0) {
            node* temp2 = temp;
            temp = temp->next;
            delete temp2;
        }
    }
    delete [] al;
    cout << "\nMemory freed.\n";
}

或者,您可以从一开始就使用 pointer 数组并动态单一分配 所有 节点,而不仅仅是邻接链,此时您的释放循环将起作用,但是您的其余代码需要进行一些更改。考虑到您对此的了解程度,我只需进行上面显示的更改并称其为好。

【讨论】:

  • 非常感谢朋友,非常感谢。所以,问题是每个 al[i] 都被删除了两次,对吧?但是,我尝试注释掉倒数第二行,即delete [] al,但仍然得到相同的错误。 :(
  • 我认为所有节点都是动态分配的。我的意思是,很明显,邻接链是动态分配的,但是每当我向链中添加一个新节点时,我都会这样做:temp-&gt;next = new node(b); 。那么,这也是动态的,对吗?
  • @SoutheeRocks 再次,并非所有人都不是。正如我所说,组成a1[] 的初始节点集是通过new node[] 向量分配的,您可以放弃该方案并简单地从一开始就使用node* 指针数组new node*[n]。毕竟,这些第一个节点的“价值”不过是i+1。不像你不能做数学。这将需要大量的代码更改。不管怎样,相信我。存储在a1[] 中的n 节点的初始向量非常动态,就像之后添加的所有邻接一样。
猜你喜欢
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2021-07-05
  • 2011-03-17
  • 1970-01-01
相关资源
最近更新 更多