tuyenle
tuyenle

Reputation: 79

Pointer being freed was not allocated even though it was allocated before

I have error that says error for object 0x7ffbaf002000: pointer being freed was not allocated. But I have printed out the memory address and it was indeed allocated before at 0x7ffbaf002000 in the function allocFlights(Flight**, int) inside the loop when flight[0] = (Flight*) malloc(sizeof(Flight) * 60). So I print out the memory address at std::cout << flight[0] << std::endl in function deAllocFlights(Flight**, int) to see if it's there and it is there at 0x7ffbaf002000 inside the loop

I don't understand why I have this problem. I'm still new at C++.

Here is the struct Flight:

typedef struct {
    int flightNum;
    char origin[20];
    char destination[20];
    Plane *plane;
}Flight;

void getAllFlights(Flight **flight) {
    FILE *file = fopen("reservation.txt", "r");
    int i = 0, totalFlights;

    if(file == NULL)
    {
        perror("Error in opening file");
    }

    fscanf(file, "%d\n", &totalFlights);
    *flight = (Flight*) malloc(sizeof(Flight*) * totalFlights);


    allocFlights(flight, totalFlights);  // Allocate here
    .
    .
    .
    deAllocFlights(flight, totalFlights);  // Error: Deallocate here
    fclose(file);
}

Function allocFlights

void allocFlights(Flight **flight, int totalFlights) {
    for (int i = 0; i < totalFlights; i++) {
        flight[i] = (Flight*) malloc(sizeof(Flight) * 60);
        std::cout << flight[i] << " " << i << std::endl;  // Print out memory address
    }
}

Function deallocFlights

void deAllocFlights(Flight** flight, int totalFlights) {
    for (int i = 0; i < totalFlights; i++) {
        std::cout << flight[i] << " " << i << std::endl; // Print out memory address
        free (flight[i]);
    }
}

Main:

int main() {
    Flight *flight;
    getAllFlights(&flight);
    free(flight);
    return 0;
}

Upvotes: 0

Views: 687

Answers (2)

Zbynek Vyskovsky - kvr000
Zbynek Vyskovsky - kvr000

Reputation: 18825

There is missing one star everywhere.

The code works with the original variable as array of pointers to Flight (or pointer to pointers to Flight). Therefore it has to be defined with double star:

int main() {
    Flight **flight;
    getAllFlights(&flight);
    free(flight);
    return 0;
}

And the same for every function:

void getAllFlights(Flight ***flight) {
    ...
    *flight = (Flight**) malloc(sizeof(Flight*) * totalFlights);

void allocFlights(Flight ***flight, int totalFlights) {
    for (int i = 0; i < totalFlights; i++) {
        // dereference the pointer first and then access array:
        (*flight)[i] = (Flight*) malloc(sizeof(Flight));

void deAllocFlights(Flight*** flight, int totalFlights) {
    for (int i = 0; i < totalFlights; i++) {
        std::cout << (*flight)[i] << " " << i << std::endl; // Print out memory address
        // dereference the pointer first and then access array
        free ((*flight)[i]);

The original code accessed directly the pointer to the variable defined in main function and used it as an array which meant it went to the address behind the variable for index 1 and even more with higher indices.

Also note, that flights is much better name for the variable and all the other parameters as it's actually array. That would make the code more clear and potentially give better chance to avoid mistakes like this.

Upvotes: 2

user1118321
user1118321

Reputation: 26345

You're deallocating your first flight twice. So the second time you deallocate it, the system tells you that it hasn't been allocated because, although it was allocated, it was also deallocated. You don't need to call free(flight); at the end because you already deallocated all flights in deAllocAllFlights(). As mentioned by David Schwartz in the comments, this is because flight[0] is the same as *flight (or as he put it *(flight + 0)).

Upvotes: 2

Related Questions