Tryer
Tryer

Reputation: 4110

Should I ONLY have to worry about new and match them with deletes?

I have a C++ code in which I have multiple data types. Importantly, I have a class:

class coordinate{
    int x, y;
    public:
     void set_values(int, int);
}

I then might say:

coordinate* origin = new coordinate;

Obviously, to recover memory allocated to origin I would finally say:

delete(origin);

So far, so good...

My question is are there any other datatypes whose deletion/destruction I MUST ABSOLUTELY MANUALLY take care of to prevent memory leakage?

The other datatypes in question are:

string (an object of this datatype seems to have an end() function), stringstream, char [].

For eg. I have a function setname() that gets called from main() repeatedly that does this:

void setname(){

    for(int k = 0; k < 10; k++){
        string NAME = "Point ";
        stringstream s;
        s << k;
        NAME += s.str();
        char name[7];
        strcpy(name,NAME.c_str());
        /*  some other stuff... */
        NAME.end(); //<--------------is stuff like this really needed?
//will memory held by NAME, s and name be automatically released as k increments?
    }
}   

Upvotes: 0

Views: 175

Answers (7)

Vlad
Vlad

Reputation: 35594

The answer is: it depends. If your code allocates anything (a string, an instance of coordinate class, a stringstream etc.) with new, some code (maybe yours) should delete it. Otherwise, if you create a string on stack and pass it around with copy constructors, you don't have to delete it.

And: NAME.end() is not needed at all. The function end() actually returns an iterator, pointing past the end of the string; it doesn't do any clean-up. So in your code the call to end() is not needed.

Upvotes: 1

Puppy
Puppy

Reputation: 147054

No, no, no. You use RAII for this - it's exception-safe.

Basically, when an object of a custom type goes out of scope in C++, it calls a special function (called the destructor). This is used to clean up all resources. It's applied automatically and, in reality, is called in all scenarios in which your program could reasonably continue, and a few that it can't.

What this means is that you never, ever have to free the memory created by a custom type- it should free itself. You will not have to free the memory allocated by std::string, nor std::stringstream. std::string::end() is about ending iteration. Typically, for any resources that require custom freeing, you will wrap them in a custom type, so that they no longer require manual freeing.

For custom types allocated with new, you can use auto_ptr, which immediately destroys the object when it goes out of scope and frees the memory, or you can use shared_ptr, which "shares" the object between all instances that point to it via some magic. There are other types of smart pointer, and for any given resource, you can write your own custom management type. This drastically increases the safety of your program for no performance loss.

Also, you should never, ever, ever use char* or any related types (char[], etc) to store strings in C++. Use std::string. Your current code is unmaintainable, as it will die or may cause random bugs if you need more than 7 characters. The C-style string functions (strcpy) are similarly extremely deprecated and should not be used.

(of course, there are exceptions to every rule, but C-style strings, you have to be very advanced to utilize their upsides correctly).

The general rule is, if you ever call a function that frees a resource outside of a destructor, you have almost certainly written your program wrong.

Upvotes: 0

Coder
Coder

Reputation: 3725

Use C++0x/TR1 shared_ptr<> if you can, they are absolutely amazing, some say with performance implications, but still, think about other alternatives only if profiler complains about shared_ptr. Shared pointers are thread safe and with very good behavior on reassign (shared_ptr<>::reset will split the references).

The only thing you should look out for is new vs new[], that's why I like c type memory allocators so much more (calloc, malloc, free) if I don't need constructors and destructors (ie. POD types).

For c type allocator you would use: shared_ptr<char> charptr((char*)calloc(10, sizof(char)), free);

P.S.: For other objects, watch out for kernel handles and GDI objects (at least on windows), they do not exactly leak memory in a classic sense, but have to be closed.

Also, c type functions often return malloc'd pointers.

Upvotes: 0

Chance
Chance

Reputation: 2699

You can always investigate the boost::shared_ptr. You still have to do the 'new', but the delete is handled internally by the shared ptr.

Upvotes: 0

Jonathan Grynspan
Jonathan Grynspan

Reputation: 43470

As a general rule: If you new it, delete it. If you new[] it, delete[] it. If you malloc() it, free() it.

Otherwise, you generally don't have to do anything. (System-specific stuff like GlobalAlloc() on Windows or CFStringCreate() on Mac OS X/iOS has its own rules. Refer to your manual/FAQ/MSDN for information on these system-specific APIs.)

Upvotes: 2

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272832

Every new should match a delete, every new [] to a delete [], and every malloc to a free (but don't use them in C++...)

Upvotes: 4

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76886

The solution to your problem is RAII.

The idea there is to bind resources to the lifetime of objects on the stack. Popular examples are smart pointers, locks and file handles.

Upvotes: 3

Related Questions