I've know that a pointer to some dynamic memory must be deleted to prevent memory leaks.

Now if say a struct/array or some other data structure, each with its own dynamic memory parts. If that structure (class, file...etc) contains the data structure goes out of scope does that automatically free the memory pointed to by the pointers or does one still need to delete each one manually?

Recommended Answers

All 5 Replies

You only/always free the memory which you explicitly allocated. If you dynamically allocate memory for a struct variable, you need to explicitly free it even though the members it contains follow the automatic memory allocation scheme.

If your struct contains instances of other structs which in turn are dynamically allocated, you must make sure that the cleanup routine walks the entire object graph and explicitly frees the allocated memory, starting from the lowest rung all the way up the object hierarchy.

let us get this straight. it is usually a technical error for a class/struct to contain members which represent unencapsulated resources (unless the class/struct itself is an encapsulating wrapper for a *single* raw resource). here is a simple example:

struct book
{
  book( const char* t, const char* a ) ;
  ~book() ; // required
  book( const book& that ) ; // required
  book& operator= ( const book& that ) ; // required
  char* title ;
  char* author ;
};

book::book( const char* t, const char* a )
{
  size_t title_len = strlen(t) ;
  title = new char[ title_len+1 ] ;
  strcpy( title, t ) ;

  size_t auth_len = strlen(a) ;
  author = new char[ auth_len+1 ] ; // this may fail (throw std::bad_alloc)
  // if it does, memory for title will leak. note: destructor of the book
  // being constructed will not (and should not) be called as the constructor
  // has not completed. so we have to scaffold this in a try/catch block.
  strcpy( author, a ) ;
}

the case with the copy constructor would be identical; the assignment operator is going to be even more messy. and as an exercise, try writing this code correctly:

struct foo { /* ... */ } ;
struct ebook : public book
{
  /*
  ...
  */
  foo* ptr ; // ebook 'owns' object pointed to by ptr
  ebook& operator= ( const ebook& that ) ; // implement this correctly
};

and once you have tried your hand at it, have a look at http://www.concentric.net/~rtgillam/pubs/assign.html and http://www.icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html

now compare this with

struct book
{
  book( const char* t, const char* a ) ;
  // compiler generated destructor, copy constructor, assignment
  std::string title ;
  std::string author ;
};

book::book( const char* t, const char* a ) : title(t), author(a)
{
  // constructor of author may fail (throw std::bad_alloc)
  // if it does, title, which has already been constructed will be
  // destroyed during the stack unwind; we have nothing to worry about.
}
struct foo { /* ... */ } ;
struct ebook : public book
{
  /*
  ...
  */
  some_owning_smart_ptr<foo> ptr ;
  ebook& operator= ( const ebook& that ) ;
};

and see how much easier programming is. this technique (called RAII) is fundamental to c++ programming.
see http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
and http://www.research.att.com/~bs/bs_faq2.html#memory-leaks

Thanks guys useful info, will put it to use after I read it couple of times...
cheers

Also plan to use class in lieu of struct.

>Also plan to use class in lieu of struct.
That changes the semantics. class and struct are similar, but not synonymous.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.