c ++删除用new分配的char指针

c++ deleting char pointer allocated with new

在这段代码中,当第一个数字是二维数组的大小时,我从文件中获取数字。

在我的代码中定义

char *filename=new char;

(我必须使用 char *filename,这是练习..) 一切正常,直到我尝试 delete 的那一刻。 deletedelete[] 都给我错误并使我的程序崩溃。

这是我的完整代码:

#include <iostream>
#include <fstream>
using namespace std;
double **readmat(char *filename, int *size)/////question 2
{
    ifstream read(filename);
    cout << filename << endl;
    if (!read)
    {
        cout << "Can't open file!" << endl;
        exit(1);
    }
    read >> *size;
    double **mat = new double*[*size];
    for (int i = 0; i < *size; i++)
    {
        mat[i] = new double[*size];
        for (int j = 0; j < *size; j++)
        {
            read >> mat[i][j];
        }
    }    
    read.close();    
    return mat;
}
int main()
{
    int size;
    char *filename = new char;
    filename = "text.txt"; 

    double **arr = readmat(filename, &size);
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            cout << arr[i][j]<<"  ,  ";
        }
        cout << endl;
    }
    cout << endl;

    delete filename; //<-------- this crashed my code
    for (int i = 0; i < size; i++)
    {
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}

这是我的文件的样子:

这是 运行 代码后控制台应用程序的样子:

这是我期望得到的结果,但我收到此错误:

有谁知道这会发生什么,我能做些什么来解决它?

char *filename = new char;
filename = "text.txt";

这会创建一个新的 char,然后将其泄漏,因为指针 filename 被重新分配给静态声明的内容。

因此,稍后您会删除原始字符之外的其他内容。

这里有多个问题(使用 new 而不是 new[],等等)。建议,忘记一切并使用std::string和STL。

这是您问题的根源:

char *filename = new char;
filename = "text.txt";

filename 不再指向动态分配的内存,因此您不能 delete 它(并且您还泄漏了 1 个字节的内存)。将您的声明更改为 const char *filename = "test.txt"; 并删除 delete filename;.

您正在尝试 delete 一个 char* 未指向分配给 new 的内存。

这一行:

char *filename = new char;

new 一些记忆(单个 char,而不是一串 char)。但是在这条线上:

filename = "text.txt"; 

您将 char* 指针更改为指向完全不同的内存,从而泄漏了您 new 编辑的内存。

然后在这一行:

delete filename;

您尝试 delete "text.txt" 文字,而不是您 newchar。这就是你崩溃的原因。

对于您正在尝试做的事情,您需要改为这样做:

char *filename = new char[strlen("text.txt")+1];
strcpy(filename, "text.txt");
...
delete[] filename;

但是,您根本不应该将 new/new[] 用于 filename。使用 std::string 代替:

#include <fstream>
#include <string>

double **readmat(const std::string &filename, int *size)
{
    std::ifstream read(filename.c_str());
    ...
}

int main()
{
    int size;
    double **arr = readmat("text.txt", &size);
    ...
}

或者:

#include <fstream>
#include <string>

double **readmat(const char *filename, int *size)
{
    ifstream read(filename);
    ...
}

int main()
{
    int size;
    std::string filename = "text.txt";

    double **arr = readmat(filename.c_str(), &size);
    // or simply:
    // double **arr = readmat("text.txt", &size);
    ...
}

然后,当您使用它时,您也不应该对矩阵使用 new[]。使用 std::vector 代替:

#include <vector>

std::vector< std::vector<double> > readmat(char *filename)
{
    ...

    int size;
    read >> size;

    std::vector< std::vector<double> > mat(size);
    for (int i = 0; i < size; i++)
    {
        mat[i].resize(size);
        for (int j = 0; j < size; j++)
        {
            read >> mat[i][j];
        }
    }    

    return mat;
}

int main()
{
    ...

    std::vector< std::vector<double> > arr = readmat("text.txt");
    size_t size = arr.size();

    for (size_t i = 0; i < size; i++)
    {
        for (size_t j = 0; j < size; j++)
        {
            std::cout << arr[i][j] << "  ,  ";
        }
        std::cout << endl;
    }
    std::cout << endl;

    return 0;
}

new char 在堆上分配一个 单个 字符。大多数将 const char* 作为参数的函数都期望指向 数组 的第一个元素的指针,其中空字符 ([=13=]) 作为分隔符(C 风格字符串).

您甚至不应该能够将字符串文字分配给 char * 类型的变量,至少在标准 C++ 中是这样。您也不需要为字符串文字动态分配内存,只需使用

const char *filename = "text.txt"; 

那么你也不要删除指向字符串文字的指针。 (这很可能是导致错误的原因,您删除了一个指向字符串文字的指针)

只需更换

char* filename = new char;

const char* filename = "text.txt";

并删除

delete filename;

这就是您的最终代码的样子

int main()
{
    int size;
    const char *filename = "text.txt"; 

    double **arr = readmat(filename, &size);
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            cout << arr[i][j]<<"  ,  ";
        }
        cout << endl;
    }
    cout << endl;

    for (int i = 0; i < size; i++)
    {
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}