Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ deleting char pointer allocated with new

In this code I am getting numbers from a file, when the first number is the size of the 2D array.

In my code I'm defining

char *filename=new char;

(I have to use char *filename, this is the exercise..) Everything works fine, until the moment I try to delete. both delete and delete[] gives me error and crashing my program.

This is my full code:

#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;
}

This is how my file looks:

enter image description here

This is what the console app looks like after running the code:

enter image description here

Which is what I am expecting to get, but I get this error:

enter image description here

Does anyone have any idea what could this happen, and what I can do to fix it?

like image 427
Alon123 Avatar asked Dec 08 '22 10:12

Alon123


2 Answers

You are trying to delete a char* that is not pointing at memory allocated with new.

On this line:

char *filename = new char;

You do new some memory (a single char, not a string of chars). But then on this line:

filename = "text.txt"; 

You change the char* pointer to point at completely different memory, thus leaking the memory you new'ed.

Then on this line:

delete filename;

You try to delete the "text.txt" literal, not the char you new'ed. That is why you crash.

For what you are attempting to do, you need to do this instead:

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

However, you really should not be using new/new[] for filename at all. Use std::string instead:

#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);
    ...
}

Alternatively:

#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);
    ...
}

And then, while you are at it, you should not be using new[] for your matrix, either. Use std::vector instead:

#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;
}
like image 110
Remy Lebeau Avatar answered Dec 10 '22 00:12

Remy Lebeau


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

This creates a new char, then leaks it because the pointer filename is reassigned to something that is statically declared.

Therefore, later on you delete something else than the original char.

Multiple issues here (using new instead of new[], etc). Suggestion, forget everything and use std::string and STL.

like image 25
Michael Chourdakis Avatar answered Dec 09 '22 23:12

Michael Chourdakis