JeffR
JeffR

Reputation: 805

Do I need to free wchar memory allocated when using 'new' or does delete[] also free it?

Trying to see the proper way to free memory, and I can't find a definitive answer. I'm sure it's out there, but I can't seem to find it and I'm a bit confused.

Here's what I'm doing. I create a new sStructUsers from sUsers, then I allocate memory for the username

    struct sStructUsers 
        {
        TCHAR *sName;
        };

    sStructUsers *sUsers = new sStructUsers[TOTALUSERS]();

    // Allocate memory for the TCHARs in sStruct
    for (INT k = 0; k < TOTALUSERS; k++)
        {
        sUsers [k].sName =  (TCHAR*)calloc(128,sizeof(TCHAR))
        }

Next, I do whatever work I need to do with the sName member

    // do work here

Now, to cleanup, do I do this:

    delete[] sUsers;

or do I do this?

    for (INT k = 0; k < TOTALUSERS; k++)
        {
        free(sUsers[k].sName);
        }
    delete[] sUsers?

I'm not sure if I need to free the memory or if delete[] would take care of it?

Upvotes: 0

Views: 1252

Answers (3)

Pablo H
Pablo H

Reputation: 659

Each allocation should be deallocated. By some code. As sklott wrote, there are tools (containers and other classes) that do the work for you. If some other code does not do it, then your code should do the deallocation.

In short, you should call both free(sUsers[k].sName) and delete[] sUsers. As it stands, deleting[] sStructUserss will not free pointers inside it.

(You could also modify sStructUsers so that its destructor does the deallocation, either directly or through a smart pointer.)

(To answerers and commenters who posted "never mix up new/delete with malloc/free", please kindle bash me with comments explaining why. It is always important to understand the rationale behind advice and best practices. Update: obviously you must not mix new+free, or malloc+delete, etc.; such functions must be properly paired lest you get heap corruption and leaks. The finer question is why not use new+delete for some allocations and malloc/calloc+free for others [finer still: CoTaskMemAlloc(), HeapAlloc(), VirtualAlloc() or other plataforms functions...]. )

Upvotes: 1

sklott
sklott

Reputation: 2849

Don't use new at all if you can help it. In modern C++ in most cases new is not needed. You can use std::vector, std::array, std::string (std::basic_string<TCHAR> maybe), std::unique_ptr or std::shared_ptr.

If you feel like you really need to use new, make special class which will handle this. I.e. for example make new in constructor and delete in destructor.

And of course, as was said in comments, never mix up new/delete with malloc/free. There is no need to use these functions in C++ at all, since this is remnants of C.

Edit: Added example, how this can be handled by class itself.

struct sStructUsers 
{
    const int MAX_NAME_SIZE = 128;
    sStructUsers()
    {
        sName = new TCHAR[MAX_NAME_SIZE];
    }
    ~sStructUsers()
    {
        delete sName;
    }
    TCHAR *sName;
};

Then you don't need any initialization/cleanup when using this class.

Note that you usually you don't need to do even this, you can define you class as this:

struct sStructUsers 
{
    std::basic_string<TCHAR> sName;
};

And have full string functionality for free. Or like this, if you really need a pointer:

struct sStructUsers 
{
    const int MAX_NAME_SIZE = 128;
    sStructUsers() : sName(new TCHAR[MAX_NAME_SIZE]) {}
    std::unique_ptr<TCHAR[]> sName;
};

Or, as I mentioned earlier, use other standard containers.

Upvotes: 5

acraig5075
acraig5075

Reputation: 10756

The comments and answers that are advising more preferable containers, more idiomatic C++, and more modern practices are all fine and well.

But your immediate question is answered by your second option

for (INT k = 0; k < TOTALUSERS; k++)
    {
    free(sUsers[k].sName);
    }
delete[] sUsers;

That will not leak memory. However your first option will leak because a mere delete[] of the array will not deallocate the heap memory of its elements.

In short, use delete[] for every new[], and free for every calloc.

(Only then perhaps refactor to be closer to C++ than a mix of C and C++)

Upvotes: 1

Related Questions