删除指针引用会使程序崩溃

时间:2014-10-05 11:48:11

标签: c++ pointers delete-operator

我正在自己学习cpp(我希望我没有吓到你),我理解指针或引用是什么,我想我得到了对指针的引用。

我编写了一个在delete[] ranking;崩溃的代码:

open(file)只是一个简单的函数,用于打开包含字符串的txt文件和每行进入zuzel结构的3个整数:

void read_file(std::ifstream & file, zuzel *& ranking)
{
    if(!open(file))
    return; //exit function if reading a file failed

    int size = 1;

    while(!file.eof())
    {
        zuzel * update = new zuzel[size];

        if(ranking != NULL) memcpy(update, ranking, (size-1)*sizeof(*ranking)); //copy existing contents

        file >> update[size - 1].nazwa >> update[size - 1].zawodnicy >> update[size - 1].mecze >> update[size - 1].punkty;// add a new team

        delete[] ranking; //delete old data
        std::cout << "tst"; //just to see if it crashes
        ranking = update;

        size++;
    }
}

int main()
{
    zuzel * rank;
    std::ifstream file;
    read_file(file, rank);
    return 0;
}

我发现你不应该删除一些你不是新的东西,但是例如代码不会崩溃:

void funk(int *& a)
{
    delete[] a;
}

int main()
{
    int a[3] = {3, 4, 6};
    int * p = a;
    funk(p);
    return 0;
}

如何修复崩溃?我不得不做一些简单的解释,为什么它会这样做。

3 个答案:

答案 0 :(得分:2)

就足够了
zuzel * rank = 0;

至于第二个代码片段,它有未定义的行为。

答案 1 :(得分:1)

zuzel * rank;
//somewhere in read_file:
delete[] ranking; //ranking is a reference to pointer;
                 //in your case it's referernce to uninitialized pointer rank

由于rank未初始化,因此它指向未知的内存部分,而您的代码只是尝试delete[]该部分...

您需要使用以下方法之一设置指向地址0的指针:

zuzel * rank=nullptr; //in C++11
zuzel * rank=NULL; //before C++11
zuzel * rank=0; //also legal, but I not recommend this

0是任何指针的特殊值,意味着它指向任何指针。

当您将指针设置为0delete[]delete时,它们什么都不做。

答案 2 :(得分:1)

因为你正在学习。请接受您可能更愿意这样做的示例。您会发现它是异常安全的并且避免使用指针(因此避免了对内存管理的需要)

main.cpp中:

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>
#include <iterator>

struct zuzel 
{
    std::string nazwa, zawodnicy, mecze, punky;
};

std::ostream& operator<<(std::ostream& os, const zuzel& z)
{
    return os << z.nazwa << ", " 
    << z.zawodnicy << ", "
    << z.mecze << ", "
    << z.punky;
}

std::vector<zuzel> read_zuzels(std::string filename)
{
    std::vector<zuzel> results;

    std::ifstream f(filename.c_str());
    f.exceptions(std::ios::badbit);

    while(!f.eof())
    {
        // add a new team
        zuzel new_zuzel;
        f >> new_zuzel.nazwa 
        >> new_zuzel.zawodnicy 
        >> new_zuzel.mecze 
        >> new_zuzel.punky;

        results.push_back(new_zuzel);
    }
    return results;
}

using namespace std;


int main()
{
    vector<zuzel> zuzels = read_zuzels("input.txt");
    copy(zuzels.begin(), zuzels.end(), ostream_iterator<zuzel>(cout, "\n"));
   return 0;
}

input.txt中:

foo1 bar1 baz1 bazzer1
foo2 bar2 baz2 bazzer2

输出:

Compiling the source code....
$g++ main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1

Executing the program....
$demo 
foo1, bar1, baz1, bazzer1
foo2, bar2, baz2, bazzer2