user6939129 user6939129 - 1 month ago 9
C++ Question

Deleting a member from a struct gives error in c++

In my code I have a struct declared like this .

int IN_USE=5;

struct ReadyQueue
{

int size;

struct process * Active; // Pointer to another struct

struct process readyProcesses[IN_USE]; // contains 5 elements of struct
process
}ready;


In the middle of my code I am doing
delete &ready.readyProcesses[2];

I get the following error during run time

"pointer being freed was not allocated"

I am a bit stuck , how to overcome this problem . It is necessary to remove that struct element from the array . Thanks in advance .

Answer

You can only delete something that you use new to create. In your case struct process readyProcesses[IN_USE] is a hardcoded array and is not dynamically created so you can't delete it. What you need is an array that is dynamically created - that means readyProcesses must be a pointer to an array.

Finally: when you new a single object you use delete but when you new an array of objects you need to use delete[] instead.

Here is an example of both:

const int IN_USE=5;

struct process
{
    /*...*/
};

struct ReadyQueue
{
    int size;
    struct process * Active; // Pointer to another struct 
    struct process * readyProcesses; // contains 5 elements of struct 
} ready;

int main()
{
    ready.Active = new struct process; // just one object
    ready.readyProcesses = new struct process[IN_USE]; // a whole array

    // now do something with ready

    delete[] ready.readyProcesses; // delete the array
    delete ready.Active; // delete the single object

    return 0;
}

If you did want to be able to delete individual array elements instead of deleting the whole array you could do the following instead but this leaves the index not pointing to anything. If you wanted to delete the entire index along with what it is pointing to (which would make the array smaller) then you should be using std::vector instead.

const int IN_USE=5;

struct process
{
    /*...*/
};

struct ReadyQueue
{
    int size;
    struct process * Active; // Pointer to another struct 
    struct process * readyProcesses[IN_USE]; // Array of pointers
} ready;

int main()
{
    ready.Active = new struct process; // just one object

    // Allocate one object for each index in the array
    for(int i=0;i<IN_USE;i++)
        ready.readyProcesses[i] = new struct process;

    // now do something with ready

    if(IN_USE>2) // if there at least three items
    {
        delete ready.readyProcesses[2]; // delete the third item
        ready.readyProcesses[2] = nullptr; // mark it as not pointing to anything
    }

    // now do more stuff with ready

    // Now delete each single object in the array
    // item 2 is nullptr so delete won't do anything with that
    for(int i=0;i<IN_USE;i++)
        delete ready.readyProcesses[i];

    delete ready.Active; // delete the single object

    return 0;
}

If you do delete an item in the middle of the program you need to set that spot to nullptr so that when you delete every index in the array at the end you won't try to delete something that has already been deleted.

If you really want to dynamically allocate everything you could:

const int IN_USE=5;

struct process
{
    /*...*/
};

struct ReadyQueue
{
    int size;
    struct process * Active; // Pointer to another struct 
    struct process ** readyProcesses; // Pointer to array of pointers
} ready;

int main()
{
    ready.Active = new struct process; // just one object
    ready.readyProcesses = new struct process * [IN_USE]; // an array of pointers

    // Allocate one object for each index in the array
    for(int i=0;i<IN_USE;i++)
        ready.readyProcesses[i] = new struct process;

    // now do something with ready

    // Now delete each single object in the array
    for(int i=0;i<IN_USE;i++)
        delete ready.readyProcesses[i];

    delete[] ready.readyProcesses; // delete the (now empty) array
    delete ready.Active; // delete the single object

    return 0;
}