class A{
private:
int i;
public:
A(){this->i = 2;}
void hello(){printf("hello is %d",i);}
void helloworld(){printf("hello world");}
}
int main(){
A *p = new A();
p =NULL;
p -> helloworld();
p ->hello();
return 0;
}
result: hello world
segment fault :11
why does the first func work,but second doesn't? I guess after we have p = NULL , segment was cleared, while we call hello(), data i already has been cleared. as consequence ,we have a error about segment。
My questions: 1. after we have p = NULL , is the heap which pointer p point to setted to NULL,or just pointer p is setted to another new heap area with NULL?
2. after we have p = NULL , heap and segment were cleared,and data i disapeared ,why pointer p still could find functions and push them into stack ?
after we have p = NULL , is the heap which pointer p point to setted to NULL,or just pointer p is setted to another new heap area with NULL?
When you set a pointer to null it means that your pointer is empty and contains no pointer value
(address), in your case above results into memory leak , you allocated some objects to a ppointer and the just decided to set the pointer to null.
1 2
delete p;
p=nullptr;//this way there is no memory leak
1 2
p -> helloworld(); /// this is an error trying to access a function from a pointer that is set to null;
p ->hello();
set a pointer to null makes it safer than than leaving it hanging over the memory (dangling pointer) which when dereferenced can lead to data corruption or some hard to debug problems.
There some Safer pointer that were introduced into the standard n they are pretty smart
Check out smart pointers.
http://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one
Because your particular compiler with particular settings did not generate instructions which leads to crash in first case.
why pointer p still could find functions
Pointer does not participate in non-virtual method binding.
There is no things like class member function on low level.
So p -> helloworld(); is actully compiled to something like:
1 2 3 4 5 6
__A__helloworld(p);
//And this function has body:
void __A__helloworld(A* this)
{
printf("hello world");
}
As you do not access anything though pointer compiler might generate code which will not touch memory area pointed to and will not cause crash if accessed though null or invalid pointer.
p ->hello(); on the other hand does try to access some variable and touches memory your program does not own, leading to crash.
according to your suggestion, the main.cpp as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
class A{
private:
int i;
public:
A(){this->i = 2;}
void hello(){printf("hello is %d",i);}
void helloworld(){printf("hello world\n");}
};
int main() {
A *p = new A();
delete p;
p = nullptr;
p -> helloworld();
//p ->hello();
return 0;
}
I could still compile and run, and get the result printed out : hello world
without an compile or runtime error about the pointer calling function.
functions are not in heap or something. They are functions. Part of the code. __A__helloworld is a function which might be generated by compiler for A::helloworld member.
You happen to get hello world output because you got lucky. Even if this seems to work, calling member functions on pointers which does not point to valid object is illegal and leads to UB.
This is likely to not crash. But it is still illegal program. It might seems to work, but it will bite you in the back in most unexpected momend (like when your program is not 10000 lines long and you are presenting it to your boss)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include <iostream>
class A{
private:
int i;
public:
A(){this->i = 2;}
void hello(){printf("hello is %d",i);}
void helloworld(){printf("hello world\n");}
};
int main()
{
A *p = new A();
delete p;
p = nullptr;
p -> helloworld(); //Calling member on null pointer; illegal, but is likely to work
((A*)&std::cin)->hello(); //Calling member on invalid pointer; invalid, but likely it will not crash
}