Reputation: 81
Quick best-practice question (note I am not allowed to use any smart pointers in this code). I am under the impression that if I pass a pointer to a function and an exceptional case occurs, then the memory is leaked if it's never deleted in either the called function or the function in which the memory was first allocated. Is it safe to delete the memory in the catch blocks or should I delete the memory in the calling function?
Example:
int main() {
object* myPtr = new object(); //dynamic memory on heap
foo(*myPtr); //pass pointer to function foo
return 0;
}
void foo(object &pointer) {
try {
/* do stuff here
with the pointer */
}
catch (const char &e) {
cout<< "An error occured: " << e << endl;
}
catch (...)
cout<< "Caught unknown exception." << endl;
}
}
Should I delete the pointer after the function returns?
int main() {
object* myPtr = new object(); //dynamic memory on heap
foo(*myPtr); //pass pointer to function foo
delete myPtr;
return 0;
}
Or in the try-catch blocks?
void foo(object &pointer) {
try {
/* do stuff here
with the pointer */
}
catch (const char &e) {
cout<< "An error occured: " << e << endl;
delete &pointer;
}
catch (...)
cout<< "Caught unknown exception." << endl;
delete &pointer;
}
}
Upvotes: 2
Views: 3220
Reputation: 595349
I am under the impression that if I pass a pointer to a function and an exceptional case occurs, then the memory is leaked if it's never deleted in either the called function or the function in which the memory was first allocated.
It is not required that the memory be freed in the same function that allocated it. But yes, in general, if the pointer is pointing at memory that was allocated with new
then it is leaked if delete
is never called on it at all, regardless of where that is actually called.
Is it safe to delete the memory in the catch blocks or should I delete the memory in the calling function?
In your example, foo()
has no concept of how the object
is allocated, so no, it is not safe to call delete
inside of foo()
.
For example, you could call foo()
using one of this instead, all of which would have problems if foo()
called delete
:
int main() {
object myObj;
foo(myObj);
return 0;
}
int main() {
std::unique_ptr<object> myPtr(new object);
foo(*myPtr);
return 0;
}
int main() {
std::vector<char> buffer(sizeof(object));
object *myPtr = new (&buffer[0]) object;
foo(*myPtr);
myPtr->~object();
return 0;
}
From foo
's perspective, it doesn't matter how the object
is allocated, as long as it is a valid object
instance going into foo()
. Since main()
decides how the object
is allocated, main()
should be the one to decide how to free it correctly, if at all.
Upvotes: 3
Reputation: 385088
When to delete pointer in try-catch block
Don't.
Delete it in main
, after the call to foo
.
In short, delete it where you created it. Anything else creates a messy asymmetry.
I am under the impression that if I pass a pointer to a function and an exceptional case occurs, then the memory is leaked if it's never deleted.
Don't know where you heard that. Forget it. It's nonsense.
Is it safe to delete the memory in the catch blocks or should I delete the memory in the calling function?
You could:
try
and in both catch
blockstry
/catch
chainand both are perfectly "safe".
But, like I said—
Should I delete the pointer after the function returns?
Right, exactly.
You have a missing *
and a capitalisation typo:
object* myPtr = new object();
// ^ ^
and in reality a version with smart pointers might look like this:
#include <iostream>
#include <memory>
struct object {};
void foo(object& obj)
{
try {
// do stuff here with the reference (not a pointer)
}
catch (const char* e) {
std::cout << "An error occured: " << e << std::endl;
}
catch (...)
std::cout << "Caught unknown exception." << std::endl;
}
}
int main()
{
auto myPtr = std::make_unique<object>();
foo(*myPtr);
}
Upvotes: 6