-2

I have buggy behaviour in C++ code that seems to be caused by the incorrect freeing of dynamically created structs. The structs are in the form:

typedef struct
{
    char *value;
} Element;

typedef struct
{
    int num;
    Element **elements;
    int *index;
} Container;

They are created like this:

Element *new_element(int size)
{
    Element *elem = new Element;
    elem->value = new char[size];
    return elem;
}

Container *new_container(int num)
{
    Container *cont = new Container;
    cont->num = num;
    cont->elements = new Element*[num];
    cont->index = new int[num];
}

What is the correct way to free these?

Schemer
  • 1,635
  • 4
  • 19
  • 39
  • 11
    The easiest way would be to re-write the code in C++, using no pointers and no calls to `new`. Then you wouldn't have to worry about freeing anything. – juanchopanza Oct 13 '14 at 16:12
  • 5
    You know, I used to keep a list of questions that could be solved by just using `std::vector` instead of `new[]`. If I didn't stop keeping it up-to-date a few months ago, my VPS' hard disk would be full by now. –  Oct 13 '14 at 16:20

2 Answers2

6

You can easily fix all freeing problems by outsourcing resource management to the compiler:

#include <cstdlib>
#include <string>
#include <vector>

struct Element {
    Element() = default;
    explicit Element(std::size_t size) : value(size, '\0') { }

    std::string value;
};

struct Container {
    explicit Container(std::size_t size) : elements(size), index(size) { }

    std::vector<Element> elements;
    std::vector<int> index;
};

For all your future resource management problems, see The Definitive C++ Book Guide and List.

Community
  • 1
  • 1
  • This might be the way to go. I'm not sure I understand the syntax. How would you write this if the struct were initialzed with more than one parameter? Say: `typedef struct { int a; int b } Element;` Done this way there is no need for deletes and frees? – Schemer Oct 13 '14 at 22:28
3

You should be doing this a sensible way. As others have pointed out, it can be made automatic. Failing that you should clean up in destructors. Failing that, however, and to answer the actual question, the syntax for deleting a new array is:

int x = new x[20];
delete [] x;

You will of course have to delete everything you new, so you will need to loop through the elements deleting each one in turn before deleting the elements array itself. You'd think someone would have wrapped that up in a convenience type cough vector cough.

Andy Newman
  • 1,178
  • 2
  • 8
  • 23