2

Must I free structure memory after using it? I have sample code:

struct aa 
{
int a;
char * b ;
    aa()
    {
    a=0;
    b= new char[255];
    }
} ;


aa *ss = new aa[3];

void fill()
{
    aa * ssss = new aa;
    aa * sss = new aa;

    sss->a=10;
    ss[0] = *sss;
    cout<<ss[0].a<<"\n";
    ss[1] = *sss;

    cout<<ss[1].a<<"\n";
    cout<<ssss[1].a<<"\n";
}

int _tmain(int argc, _TCHAR* argv[])
{


    fill();
    delete(ss);
}

Must I do delete(ssss) at the end of fill?

Must I delete ss array of structure at the end of main?

Must I create destruct or to structure ss that frees *b memory?

What about classes is it the same logic?

vico
  • 17,051
  • 45
  • 159
  • 315
  • 2
    I'd say no to everything: use `std::string` for `b`, `std::array` (or `std::vector`) for `ss`, and normal objects for `ssss` and `sss`. – chris Jul 21 '12 at 14:47
  • @BenVoigt: Did anyone say it was? Or are you just complaining about the unnecessary parentheses? – Mike Seymour Jul 21 '12 at 14:57
  • For gawd's sake, give `aa` a destructor. It allocated its memory; it should be the one to free it. – cHao Jul 21 '12 at 14:58
  • 1
    @Mike: The end problem is use of `delete` where `delete[]` is required. The extra parentheses suggest to me that the root cause is someone thinking `delete` is a function. – Ben Voigt Jul 21 '12 at 14:58
  • 2
    Along with the problems others have already noted, there's also the minor detail of undefined behavior. Leaving out some unrelated code, we have: `aa * ssss = new aa;` [ ... ] `cout< – Jerry Coffin Jul 21 '12 at 15:02
  • 3
    @cHao: Bad advice, IMO. Instead of adding a destructor (and, to actually work, probably a copy constructor and assignment operator) just define `aa` as: `struct aa { int a; char b[255]; };` – Jerry Coffin Jul 21 '12 at 15:05
  • @Jerry: Yeah, that works a lot better in this case. I was initially assuming he allocated the array separately for some reason, but it could easily be that he just didn't know better. – cHao Jul 21 '12 at 17:03

4 Answers4

8

Must I do delete(ssss) at the end of fill?

Yes, you must delete anything created with new. However, there's no need to use new here, just make it automatic:

void fill() {
    aa ssss; // automatically destroyed on exit from the function
}

Must I delete ss array of structure at the end of main?

Yes, but it is an array, so must be deleted as an array:

delete [] ss;
       ^^

But again, there's no reason for this to be dynamically allocated:

aa ss[3]; // automatically destroyed on exit from the program

Must I create destruct or to structure ss that frees *b memory?

If you really want to use a raw pointer to manage the dynamic array, then yes. You will also need to think about a copy constructor and copy-assignment operator (per the Rule of Three) to make the class safe to use. Alternatively, use a smart pointer or container to manage the memory for you:

struct aa 
{
    int a;
    std::vector<char> b ;

    aa() : a(0), b(255) {}
} ;

What about classes is it the same logic?

Yes, the rule is always the same: anything created with new must be destroyed with delete. Managing objects is much easier if you avoid dynamic allocation where possible, and use smart pointers, containers and other RAII classes when you really do need it.

Community
  • 1
  • 1
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
5

If you use new, you must use delete to avoid a memory leak. If you declare a variable on stack, it will be freed automatically when you exit the scope.

void something();
{
    aa b = new aa();
    // Do something
    delete b; // You must use delete
}

void something();
{
    aa b();
    // Do something
    // You don't have to use delete
}

In your specific case, it is not strictly necessary to use delete, because the program is going to terminate anyway and all the assigned memory will be freed by the OS.

It is still a good practice to do so, so as to be consistent (though there are some specific cases where you DON'T want to do this because freeing a lot of complex objects can take some time thus slowing down the program termination).

Anyhow, using naked pointers is not such a good idea in C++ since there are many so-called smart pointers (such as shared_ptr and unique_ptr) that take care of calling the destructor and freeing the memory after they run out of scope.

PS: In your code, you will have a memory leak, because the aa structure uses new inside the constructor and does not call delete in destructor.

  • Using `auto_ptr` is discouraged for good reasons. If using c++11 I would suggest `unique_ptr` instead, otherwise its either `shared_ptr` or boost `unique_ptr` – Grizzly Jul 21 '12 at 14:53
  • Yep, lots of programs love to free every little bit of memory at shutdown. While I can understand the temptation, as a user I personally prefer not having to wait several seconds while it does so.. – Voo Jul 21 '12 at 14:54
  • ..or forever, if some thread/s is/are stuck. I cannot understand the temptation to write unnecessary code at all, especially unnecesary code that is difficult, awkward, messy, complex,needs testing on every OS/multicore environment to make sure it still works and adds nothing to the app runtime functionality. The more code, the more bugs :( – Martin James Jul 21 '12 at 15:04
0

YES

Please, please, please free your memory. I won't go into detail here, but take a look at this answer: Can a memory block allocated by using operator new/malloc persist beyond end of program execution?

Community
  • 1
  • 1
Linuxios
  • 34,849
  • 13
  • 91
  • 116
0

Rule of thumb in C/C++:

  • Allocated with new? free the memory with delete
  • Allocated with malloc, calloc, realloc? free the memory with free(void*)
cybertextron
  • 10,547
  • 28
  • 104
  • 208