开发者

When to delete[] a pointer c++?

开发者 https://www.devze.com 2023-03-14 04:47 出处:网络
I\'ve been toying with c++ for a little while, and coming from java one of the most confusing aspects for me is memory management. For example, lets say I have a method, and in that method I declare a

I've been toying with c++ for a little while, and coming from java one of the most confusing aspects for me is memory management. For example, lets say I have a method, and in that method I declare a pointer to an object, i want to set that pointer to an attribute of another object using a get method:

SubObject *mySubObject = anotherObject.getSubObject();

My question is, what happens to this pointer when the method ends? should i use the following before it ends?

delete mySubObject;

What if i don't delete it? Does it remain until the entire program ends?

I've tried googling around for basic memory management tutorials for c++, but i typically find more advanced stuff thats way o开发者_开发百科ver my head, any referals would be appretiated.


Tracking memory management can be a burden, the best advice is to avoid it in as much as possible and make it explicit by avoiding raw pointers. If you only need temporary access to a variable that is held somewhere else (in your example, it is a member of a different object, and thus managed there) you should not delete it, and it will be better if you just hold a reference rather than a pointer, as references make explicit the fact that you are not managing that resource.


If that getSubObject() method simply returns a pointer to a previously allocated mySubObject, you should not delete it, because that should be the responsibility of the class that allocated it in the first place. Also that pointer might not even have been allocated through a new and be in the stack, so deleting it could potentially lead to bigger problems.

As a rule of thumb, delete what you have new'd. Of course that heavily depends on the layout of the programming.


To answer the question in your post title, you should use delete[] if and only if you allocated memory with new[]. You should use delete if and only if your used new to allocate memory.

int *array = new int[10];
int *ptr = new int;
...
delete[] array;
delete ptr;

To answer your post, you should ask yourself when your code allocates memory. In fact, you should think of memory as a resource, like a file handle or network connection. Anytime you open a file in C++ or Java, after you are done, you should close the files. Likewise, anytime you allocate memory in C++, you should free it. The tough question is when you should free the memory. So does the method

anotherObject.getSubObject();

return a pointer to a newly allocated object? Whose job is it to free the memory pointed to by the pointer returned in the above method?

If the above method uses new and returns a pointer to that newly allocated memory, then the client (the programmer who called the method) must delete the memory. However, if the pointer returned by the method is freed by the object anotherObject when its destructor is called, then the client should NOT free the memory referenced by the pointer.

If you are new to C++ from Java, you should definitely try using references when possible, and check out smart pointers. The nice thing about smart pointers is that they provide automatic memory management (you don't have to worry about deleting after you have newed an object).


As you just trying to learn basic C++ memory management, forget all the answers about references and smart pointers.

Learn the basics and later you can return to these "advanced" subjects.


To answer the question in the topic: In C++ you use delete [] to delete an array allocated with new[]. Ie:

int *a = new int[10];  // Allocate 10 ints and save ptr in a.
for (int i=0; i<10; i++) {
    a[i] = 0;    // Initialize all elements to zero.
}
delete [] a; // Free memory allocated for the a array.

As Gustavo correctly points out the reason for the [] in the delete invocation is to make sure the destructor gets invoked in each of the elements of the array.


Without knowing details about getSubObject(), there is no way to know how to truly answer the question. The answer should lie in the documentation for getSubObject() (But not everyone follows that should.) That documentation might be in some old-style document, some doxygen (or similar) page, the header file that declares getSubObject(). If worst comes to worst, you'll need to look at the source code that defines getSubObject(), assuming that the source is available.

When reading that documentation/header/source, you should be looking for an answer to the question "Does getSubObject() allocate memory that the caller must delete, or does it merely return a pointer to an existing object?" With a name like getSubObject() I would expect the latter is the case. I would expect the former if the name of the function was createSubObject().


There is no right answer into that. If the pointer returned by the member function (or method if we are using java lingo) is pointing into an object allocated in the stack, your program will crash if use the keyword delete on it.

Should the caller or the callee be responsible for memory management if you are using the free storage? If another person calls the member function, Now you have a dangling pointer. And what about if the callee is using RAII?

Since you are learning (kudos for that) , try to learn the basics of memory management first. Once you have a basic understanding of memory, you will be more comfortable with C++ and memory management.

If you are doing production code, and you have to do it in C++. The safest way to avoid all these issues is to use dynamic memory allocation only when you need to, until you have a better understanding of it. In my opinion, even when you have a good understanding of dynamic memory allocation, you should have a good reason why you are using it.

Good luck,

Armando.


In C++, you have to manage the memory allocation all on you own, there is no garbage collection of bits you have forgotten to clean up as java/C# and any other modern language has. If you lose track of memory, at best it's leaked, at worst, you continue to use it while something else does. It's a hard problem to solve, very few, if any, C++ programers get this right, so smart pointers and other esoteric advanced magic is performed to get around these issues in C++. @yi_H is correct, get to understand the basics of basic memory allocation, so you know why Smart Pointers are such a good idea.

Without smart pointers, while a few of the answers above have eluded to it, "ownership" is the most critical thing to understand. Whenever you have a pointer to a block of memory, you must know who owns it. If you own it, you must free it before it goes out of scope or it's lost. If you give someone else a copy of it, ensure that you define who owns it, and when the owner can/will/should free it. If you cannot do this, you are hosed. As a rule, C++ libraries are notoriously bad at documenting this, so in the absence of clear information, assume you do not own it (Do not delete it and potentially create a memory leak) in preference to deleting it and creating hard to find defects. Use Valgrind to find memory leaks on the working program.

To avoid the worst pitfalls, obey some simple rules. Use locals and references in preference to heap (new). When returning allocated memory, clearly document the ownership and life cycle of the allocated memory. Avoid making copies of pointers to allocated memory, copy the data where possible. When making copies of pointers, make the scope as small and short life time ass possible. Much use of pointers is done (badly) in the name of efficiency- a program that runs slowly is far more efficient that one that randomly core dumps.

i.e. Limit the use of the keyword "new".


Well the design shouldn't be like this that you get a pointer from another object and delete it.

SubObject *mySubObject = anotherObject.getSubObject();
delete mySubObject;

If you delete mySubObject in that point anotherObject class functions may still use it. You should follow OOP approaches. The object that is returned by getSubObject() function should be created/allocated memory from constructor and deallocated in a destructor. And yes reference is better here so that mistakenly a delete is not performed outside the class. Thanks.

0

精彩评论

暂无评论...
验证码 换一张
取 消