I've got a couple of questions regarding pointers. First:
ObjectType *p;
p->writeSomething();
Why is it possible to call a method on an object when the pointer hasn't been initialized? If I run that code I get the output from "writeSomething()" in my console window. Second:
ObjectType *p;
if(p==NULL)
cout<<"Null pointer";//This is printed out
p = new ObjectType;
delete p;
if(p==NULL)
cout<<"Null pointer";
else
cout<<"Pointer is not null";//This is printed out
Why isn't the pointer null in the second if statement and how do I check if a pointer isn't pointing to any memory address? I'm also wondering if there is any way to check if some memory hasn't been released when a program is done executing. For example, if you forget to write 1 delete statement in the code.
The first code is undefined behavior, anything can happen, even appearing to work. It's probably working because the call is resolved statically, and you're not accessing any members of the class.
For the second snippet delete doesn't set the pointer to NULL, it just releases the memory. The pointer is now dangling, as it points to memory you no longer own.
Your code does of course exhibit undefined behaviour, but here's an example of why it may appear possible to call a member function even if there is no object: If the member function doesn't refer to any member objects of the class, then it will never need to access any part of the memory which you haven't initialized. That means, your member function is essentially static.
As you know, member functions can be considered as normal, free functions which have an implicit instance object reference argument. For example, a simple class Foo defined like this,
struct Foo
{
void bar() { std::cout << "Hello\n"; }
};
could be implemented as a single, free function:
void __Foo_bar(Foo * this)
{
std::cout << "Hello\n";
}
Now when you say Foo * p; p->bar();, this amounts to a free function call __Foo_bar(p);. You end up passing an invalid pointer to the function, but since the function never makes use of the pointer, no harm is done.
On the other hand, if your class had a member object, like int Foo::n;, and if the member function was trying to access it, your implementation would try and access this->n, which would very likely cause an immediate problem since you'd actually be dereferencing an invalid pointer.
delete p;
deallocates memory, but it does not change the value of the address stored in p.
There is no method in standard C++ to detect that a pointer is referring to invalid memory. It is your responsibility not to de-reference an invalid pointer.
Your first example is undefined behaviour. One of the possible outcomes of undefined behaviour is that the program works the way you intended it to. Again, it is your responsibility not to write programs with undefined behaviour.
In your code, writeSomething() is probably a non-virtual member function that does not de-reference this which is why it happens to work for you, on your compiler. Most likely if you tried to refer to some member data fields then you would encounter a runtime error.
delete would call upon the destructor of ObjectType followed by de-allocation of memory but it doesn't explicitly makes your pointer NULL
That is something you have to do as a good programming practice.
Related
Is it always wise to use NULL after a delete in legacy code without any smartpointers to prevent dangling pointers? (bad design architecture of the legacy code excluded)
int* var = new int(100);
delete var;
var = NULL;
Does it also make sense in destructors?
In a getter, does it make sense to test for NULL in second step?
Or is it undefinied behavier anyway?
Foo* getPointer() {
if (m_var!=NULL) { // <-is this wise
return m_var;
}
else {
return nullptr;
}
}
What about this formalism as an alternative? In which cases will it crash?
Foo* getPointer() {
if (m_var) { // <-
return m_var;
}
else {
return nullptr;
}
}
(Edit) Will the code crash in example 3./4. if A. NULL is used after delete or B. NULL is not used after delete.
Is it always wise to use NULL after a delete in legacy code without any smartpointers to prevent dangling pointers? (bad design architecture of the legacy code excluded)
int* var = new int(100);
// ...
delete var;
var = NULL;
Only useful if you test var afterward.
if scope ends, or if you set other value, setting to null is unneeded.
Does it also make sense in destructors?
nullify members in destructor is useless as you cannot access them without UB afterward anyway. (but that might help with debugger)
In a getter, does it make sense to test for NULL in second step? Or is it undefinied behavier anyway?
[..]
[..]
if (m_var != NULL) and if (m_var) are equivalent.
It is unneeded, as, if pointer is nullptr, you return nullptr,
if pointer is not nullptr, you return that pointer, so your getter can simply be
return m_var;
Avoid writing code like this
int* var = new int(100);
// ... do work ...
delete var;
This is prone to memory leaks if "do work" throws, returns or otherwise breaks out of current scope (it may not be the case right now but later when "do work" needs to be extended/changed). Always wrap heap-allocated objects in RAII such that the destructor always runs on scope exit, freeing the memory.
If you do have code like this, then setting var to NULL or even better a bad value like -1 in a Debug build can be helpful in catching use-after-free and double-delete errors.
In case of a destructor:
Setting the pointer to NULL in a destructor is not needed.
In production code it's a waste of CPU time (writing a value that will never be read again).
In debug code it makes catching double-deletes harder. Some compilers fill deleted objects with a marker like 0xDDDDDDDD such that a second delete or any other dereference of the pointer will cause a memory access exception. If the pointer is set to NULL, delete will silently ignore it, hiding the error.
This question is really opinion-based, so I'll offer some opinions ... but also a justification for those opinions, which will hopefully be more useful for learning than the opinions themselves.
Is it always wise to use NULL after a delete in legacy code without any smartpointers to prevent dangling pointers? (bad design architecture of the legacy code excluded)
Short answer: no.
It is generally recommended to avoid raw pointers whenever possible. Regardless of which C++ standard your code claims compliance with.
Even if you somehow find yourself needing to use a raw pointer, it is safer to ensure the pointer ceases to exist when no longer needed, rather than setting it to NULL. That can be achieved with scope (e.g. the pointer is local to a scope, and that scope ends immediately after delete pointer - which absolutely prevents subsequent use of the pointer at all). If a pointer cannot be used when no longer needed, it cannot be accidentally used - and does not need to be set to NULL. This also works for a pointer that is a member of a class, since the pointer ceases to exist when the containing object does i.e. after the destructor completes.
The idiom of "set a pointer to NULL when no longer needed, and check for NULL before using it" doesn't prevent stupid mistakes. As a rough rule, any idiom that requires a programmer to remember to do something - such as setting a pointer to NULL, or comparing a pointer to NULL - is vulnerable to programmer mistakes (forgetting to do what they are required to do).
Does it also make sense in destructors?
Generally speaking, no. Once the destructor completes, the pointer (assuming it is a member of the class) will cease to exist as well. Setting it to NULL immediately before it ceases to exist achieves nothing.
If you have a class with a destructor that, for some reason, shares the pointer with other objects (i.e. the value of the pointer remains valid, and presumably the object it points at, still exist after the destructor completes) then the answer may be different. But that is an exceedingly rare use case - and one which is usually probably better avoided, since it becomes more difficult to manage lifetime of the pointer or the object it points at - and therefore easier to introduce obscure bugs. Setting a pointer to NULL when done is generally not a solution to such bugs.
In a getter, does it make sense to test for NULL in second step? Or is it undefinied behavier anyway?
Obviously that depends on how the pointer was initialised. If the pointer is uninitialised, even comparing it with NULL gives undefined behaviour.
In general terms, I would not do it. There will presumably be some code that initialised the pointer. If that code cannot appropriately initialise a pointer, then that code should deal with the problem in a way that prevents your function being called. Examples may include throwing an exception, terminating program execution. That allows your function to safely ASSUME the pointer points at a valid object.
What about this formalism as an alternative? In which cases will it crash?
The "formalism" is identical to the previous one - practically the difference is stylistic. In both cases, if m_var is uninitialised, accessing its value gives undefined behaviour. Otherwise the behaviour of the function is well-defined.
A crash is not guaranteed in any circumstances. Undefined behaviour is not required to result in a crash.
If the caller exhibits undefined behaviour (e.g. if your function returns NULL the caller dereferences it anyway) there is nothing your function can do to prevent that.
The case you describe remains relatively simple, because the variable is described in a local scope.
But look for example at this scenario:
struct MyObject
{
public :
MyObject (int i){ m_piVal = new int(i); };
~MyObject (){
delete m_piVal;
};
public:
static int *m_piVal;
};
int* MyObject::m_piVal = NULL;
You may have a double free problem by writing this:
MyObject *pObj1 = new MyObject(1);
MyObject *pObj2 = new MyObject(2);
//...........
delete pObj1;
delete pObj2; // You will have double Free on static pointer (m_piVal)
Or here:
struct MyObject2
{
public :
MyObject2 (int i){ m_piVal = new int(i); };
~MyObject2 (){
delete m_piVal;
};
public:
int *m_piVal;
};
when you write this:
MyObject2 Obj3 (3);
MyObject2 Obj4 = Obj3;
At destruction, you will have double Free here because Obj3.m_piVal = Obj4.m_piVal
So there are some cases that need special attention (Implement : smart pointer, copy constructor, ...) to manage the pointer
I get a bad feeling about this code
widget* GetNewWidget()
{
widget* theWidget = (widget *) malloc(sizeof(widget));
return theWidget;
}
Firstly, one should never cast the result of malloc() (nor, I suspect, use it in C++ (?)).
Secondly, won't theWidget be allocated on the stack?
If so, won't the caller trying to access after this function returns be undefined behaviour?
Can someone point to an authoritative URL explaining this?
[Update] I am thinking of this question Can a local variable's memory be accessed outside its scope?
In summary: this code is perfectly fine
Returning a pointer is like returning an int: the very act of returning creates a bitwise copy.
Step, by step, the code works as follows:
malloc(sizeof(widget));
Allocates a block of memory on the heap[1], starting at some address (let's call it a), and sizeof(widget) bytes long.
widget* theWidget = (widget *) malloc(sizeof(widget));
Stores the address a on the stack[2] in the variable theWidget. If malloc allocated a block at address0x00001248, then theWidget now contains the value 0x00001248, as if it were an integer.
return theWidget;
Now causes the value of a to be returned, i.e., the value 0x00001248 gets written to wherever the return value is expected.
At no point is the address of theWidget used. Hence, there is no risk of accessing a dangling pointer to theWidget. Note that if your code would return &theWidget;, there would have been an issue.
[1] Or it might fail, and return NULL
[2] Or it might keep it in a register
On the stack you just allocated a pointer, it's not related to the object itself. :)
I never use malloc (it's a C thing, you shouldn't use it in C++), thus i am not sure, but i hardly believe it's undefined behaviour.
If you would write this: widget* theWidget = new widget(); it should work correctly.
Even better if you use smart pointers if you have C++11
std::unique_ptr<widget> GetNewWidget()
{
std::unique_ptr<widget> theWidget(std::make_unique<widget>());
return theWidget;
}
Or in this case you can write even smaller code, like this:
std::unique_ptr<widget> GetNewWidget()
{
return std::make_unique<widget>();
}
The above version will clean out the memory as soon as unique pointer go out of scope. (unless you move it to another unique_ptr) It's worth some time to read about memory management in C++11.
As I understand if the member function has been called using pointer to an object which is allocated dynamically, the object would get delete. But if the member function has been called using the object, which is allocated statically, then what will happen ?
class sample
{
int i;
public:
void func()
{
delete this;
}
};
void main()
{
sample *s = new sample;
s->fun();
sample s1;
s1.fun();
}
Deleting a pointer inside a member function is OK, as long as you know how that pointer has been allocated. There is no portable way of knowing that from just a pointer alone.
If a function is passed a pointer that has not been allocated dynamically, and the function calls delete on that pointer, it is undefined behavior. Moreover, even pointers to dynamic objects allocated as arrays cannot be freed with the regular delete operator: you must use delete[] on them. A simple rule is that when you do not know the origin of a pointer, you do not call delete on it.
You can only use delete if the object was allocated using new. Simple as that. Therefore the first example you gave is legal, the second is not. The second case is likely to crash, or worse, cause heap corruption and crash at a seemingly random memory allocation somewhere far removed from the problem.
If you call delete this inside any member function of object which is statically allocated , then calling delete this will crash at runtime . Because when this object will go out of scope , compiler will automatically call destructor , which will try to delete object which no longer exists.
I would like to have a class contain a std::unique_ptr initialized by the constructor then used elsewhere in the class.
So I've got a class that contains a std::unique_ptr like this:
class ObjectA
{
public:
ObjectA();
~ObjectA();
void SomeFunction();
private:
std::unique_ptr<ObjectB> myPointer;
}
Then in the class's source file myPointer is setup in the constructor and used in SomeFunction().
ObjectA::ObjectA()
{
ObjectC objectC;
myPointer = std::move(std::unique_ptr<ObjectB>(objectC.getPointer())); //setup pointer
}
ObjectA::~ObjectA() {}
void ObjectA::SomeFunction()
{
//use myPointer here
}
The problem though, is that I can't use myPointer in SomeFunction(), and here's why.
Obviously myPointer must be allocated on the heap to assure it doesn't get destroyed when the constructor is done executing. Assume that ObjectC and consequentially it's functions are from an external library. When I call ObjectC::getPointer() the pointer that's return is probably allocated on the stack apposed to the heap. Now I assume this is the case because right after the constructor has finished executing I get an error.
Basically I'm relying on a function to give me a pointer with wich I can then use elsewhere. However, the function allocates the object on the stack instead of the heap.
Is there some special way to solve this problem, maybe with a double pointer? Or will I just have to call ObjectC::getPointer() every time I want to use the pointer inside each execution block? If I had lots of functions inside ObjectA which rely on myPointer then calling ObjectC::getPointer() per function would be redundant, but I don't know if there is a better way to fix this, and I feel like a function (ObjectC::getPointer()) shouldn't force me into that redundancy.
When you call ObjectC::getPointer(), you don't just get "a" pointer. The function must specify what operations are valid on the pointer, and in particular how it should be disposed.
Usually, that would be delete, but it could also be e.g. fclose. You'll have to read the documentation. If the lifetime of the returned pointer matches that lifetime of objectC, then the lifetime of objectC should match myPointer. So it probably should be a member, and that in turn means that myPointer might be redundant. You could just substitute private: ObjectB& getB() { return *myObjectC.GetPointer(); }
#include <cstdio>
class baseclass
{
};
class derclass : public baseclass
{
public:
derclass(char* str)
{
mystr = str;
}
char* mystr;
};
baseclass* basec;
static void dostuff()
{
basec = (baseclass*)&derclass("wtf");
}
int main()
{
dostuff();
__asm // Added this after the answer found, it makes it fail
{
push 1
push 1
push 1
push 1
push 1
push 1
push 1
push 1
push 1
push 1
}
printf("%s", ((derclass*)basec)->mystr);
}
Ugh. This is one of those "don't ever do this" examples. In dostuff, you create a temporary of type derclass, take its address, and manage to pass it outside of dostuff (by assigning it to basec). Once the line creating the temporary is finished, accessing it via that pointer yields undefined behavior. That it works (i.e. your program prints "wtf") is certainly platform dependent.
Why does it work in this specific instance? To explain this requires delving deeper than just C++. You create a temporary of type derclass. Where is it stored? Probably it's stored as a very short lived temporary variable on the stack. You take it's address (an address on your stack), and store that.
Later, when you go to access it, you still have a pointer to that portion of your stack. Since nobody has since come along and reused that portion of the stack, the object's remnants are still there. Since the object's destructor doesn't do anything to wipe out the contents (which is, after all, just a pointer to "wtf" stored somewhere in your static data), you can still read it.
Try interjecting something which uses up a lot of stack between the dostuff and printf calls. Like, say, a call to a function which calculates factorial(10) recursively. I'll bet that the printf no longer works.
basec = (baseclass*)&derclass("wtf");
Here a temporary object of derclass is created and destructed immediately when ; is encountered in dostuff() function. Hence, your basec pointer points to invalid object.
As aJ notes, the temporary object you create is immediately destroyed. This doesn't exactly 'work': you're into undefined behaviour which may legally cause your monitor to catch on fire the next time you run it!
Hint: undefined behaviour - just say no.
Note that basec = (baseclass*)&derclass("wtf"); causes undefined behavior to be invoked. The problem is that derclass("wtf") creates a temporary object (of type derclass) the & in front of it will take the temporary object's address, which will then be assigned to basec. Then, at the end of the full expression, the temporary object will be destroyed, leaving basec with a pointer to a no longer existing object. When you later access this piece of memory (in (derclass*)basec)->mystr) you are invoking undefined behavior.
Since it's the nature of undefined behavior to allow the program to do anything it pleases, your program might even work as if the object still existed. But it might as well crash, format your hard drive, or invoke nasty nasal demons on you.
What you would have to do is assign the address of an object to basec which isn't destroyed as long as you use it. One way to do this would be to dynamically create an object: basec = new derclass("wtf").
It creates the temporary variable on the stack because it's a local variable to the dostuff() function. Once the dostuff function exits, the stack rolls back possibly leaving the object on the memory stack exactly as it should be. Now your pointer is pointing to a spot on the stack that hopefully won't get clobbered by the call to printf when it passes in a pointer to stack memory that is no longer being used.
Usually stack that isn't being used isn't overwritten if you don't call other functions.
You could actually do some damage by calling a few functions, and then changing the value of mystr. The characters of text would then become part of the executable code. Hacker's dream.
Try something like this:
void breakStuff()
{
char dummy[3];
strcpy( dummy, "blahblahblahblahblah" );
int i = 7;
i = i + 8;
i = i + 22;
printf( "**%d**", i );
}
The strcpy will write PAST the local variable and overwrite the code. It'll die horribly. Good times, noodle salad.
The instance pointed to by basec is a derclass, the casts just tell the compiler what to think of the pointer at any given moment.
Edit: strange that you can access the temporary later on. Does this still work if you allocate some other data on the stack?
Do you get a compiler warning from the (baseclass*) cast?