This question already has answers here:
What will happen when I call a member function on a NULL object pointer? [duplicate]
(6 answers)
Closed 8 years ago.
How does it work?
QDesktopWidget *Desktop=NULL;
auto Desktop_Rect=Desktop->screenGeometry();
pDebug()<<Desktop_Rect.width()<<","<<Desktop_Rect.height(); //1440,900
If I rewrite it as following:
auto Desktop_Rect=QDesktopWidget::screenGeometry();//Error:screenGeometry is not a static method.
pDebug()<<Desktop_Rect.width()<<","<<Desktop_Rect.height();
Basically your question has less to do with Qt but with C++.
The pointer isn't required to call the method, but the type of the pointer.
The method might not use this, so it runs the code just fine.
The bahaviour should be undefined, depends on the implementation of screenGeometry method.
P.S. Compile with warnings AND DON'T IGNORE THEM (suggested by Jeoren in comments)
This works in all cases where you call a class method on a NULL-pointer. The compiler does not (cannot) check for valid values of the pointer at compile time. It only looks at the type of the pointer, and as long as that checks out (in this case, the QDesktopWidget class does indeed have a function called screengGeometry that accepts 0 parameters) it will happily compile your code.
However, at runtime, this will most likely crash as soon as the code in that function accesses the class's data members. That is when it tries to dereference the "this" pointer, which in this case is NULL. The fact that your first example runs successfully simply means it does not access instance data, but only static or global data.
The second snippet is simply a completely different case, where you are trying to call a method as if it was static, while it is not. This results in the entirely correct and helpful error message you quote.
Ask yourself this though: What should the function return when you call screenGeometry when there is no instance to which it belongs. Both code snippets try to do something nonsensical.
Related
This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 1 year ago.
I was given the following as an interview question:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
What will happen when this code is executed, and why?
See also:
When does invoking a member function on a null instance result in undefined behavior?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun" since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
By the standard, this is undefined behavior and therefore a very bad thing. In reality of most programming platforms (across both X86 and several other architectures) this will run fine.
Why? Consider how class functions are implemented in C++. This isn't a virtual function, therefor this can be a static call to a known address.
In x86 assembly, we can see this as
mov A, 0
mov ecx, A
call a__fun
since a__fun requires no instance data, even though it receives a null this pointer, nothing will happen.
Still shitty code and any compiler will scream, but it can run.
The most likely behavior, on most modern computers, is that it will run, and print "fun", because:
C++ doesn't check whether the pointer is NULL before calling the function
fun() is not virtual, so there's no need to refer to a vtable to call fun()
fun() never access any member variables in A so it doesn't need to dereference
the null this pointer.
We can't know what will. Everything can happen, because the program exposes undefined behavior. See Does invoking a member function on a null instance cause undefined behavior?.
I have tried multiple times,all the time output is coming "fun" this is because function fun is independent of instance a. while calling a->fun(); a points to 0 so this is undefined behavior but in most of the compilers there should be no crash.
Three points might help:
1) All Functions are stored in code or text section.
2) Non Virtual functions are resolved at complie time.
3) While calling to member functions of class, we pass current object as this pointer to that function.
Coming to your question , here fun() function is already in memory(code section / text section).
As function fun() is non virtual , it will be resolved at complie time (i.e, for this line it will jump to instruction X at code section with this pointer as NULL).
As no member variable and no virtual function are used/called in fun() function, it is working fine.
This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 1 year ago.
I was given the following as an interview question:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
What will happen when this code is executed, and why?
See also:
When does invoking a member function on a null instance result in undefined behavior?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun" since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
By the standard, this is undefined behavior and therefore a very bad thing. In reality of most programming platforms (across both X86 and several other architectures) this will run fine.
Why? Consider how class functions are implemented in C++. This isn't a virtual function, therefor this can be a static call to a known address.
In x86 assembly, we can see this as
mov A, 0
mov ecx, A
call a__fun
since a__fun requires no instance data, even though it receives a null this pointer, nothing will happen.
Still shitty code and any compiler will scream, but it can run.
The most likely behavior, on most modern computers, is that it will run, and print "fun", because:
C++ doesn't check whether the pointer is NULL before calling the function
fun() is not virtual, so there's no need to refer to a vtable to call fun()
fun() never access any member variables in A so it doesn't need to dereference
the null this pointer.
We can't know what will. Everything can happen, because the program exposes undefined behavior. See Does invoking a member function on a null instance cause undefined behavior?.
I have tried multiple times,all the time output is coming "fun" this is because function fun is independent of instance a. while calling a->fun(); a points to 0 so this is undefined behavior but in most of the compilers there should be no crash.
Three points might help:
1) All Functions are stored in code or text section.
2) Non Virtual functions are resolved at complie time.
3) While calling to member functions of class, we pass current object as this pointer to that function.
Coming to your question , here fun() function is already in memory(code section / text section).
As function fun() is non virtual , it will be resolved at complie time (i.e, for this line it will jump to instruction X at code section with this pointer as NULL).
As no member variable and no virtual function are used/called in fun() function, it is working fine.
This question already has answers here:
Is it legal C++ to test the this-pointer in a member function?
(5 answers)
Closed 6 years ago.
So i'm aware that this is a reference to the class itself, however I can't really tell what it does in an if statement
What does the following code do?
if(this)
{
//Code goes here...
}
I'm fairly sure it is checking if the class is not null, but a further explanation would be great!
this pointer is a constant pointer that holds the memory address of the current object. So, technically this will check whether it is null or not which will not be null in member function. Since you will not be able to call a class until you have its object and in abstract classes you can't use this anyway. So, this if doesn't make much sense.
It's attempting to check to see if the method was called on a NULL pointer, e.g. something like this:
Foo * foo = NULL;
foo->TheMethod();
However, that isn't a valid technique, since calling a method (even a non-virtual method!) on a NULL pointer is undefined behavior and so the test won't work reliably.
It is indeed checking if this != nullptr. However by the time you reach this statement, you have already passed from undefined behavior. Because this is available only in a class method and calling such method with nullptr is UB.
Hence such statement never serves any valid purpose.
Besides UB, also remember that such checks are useful only when called with a pointer. They are irrelevant for object/reference. If the method is virtual then most of the architecture would crash the code before reaching that if.
This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 1 year ago.
I was given the following as an interview question:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
What will happen when this code is executed, and why?
See also:
When does invoking a member function on a null instance result in undefined behavior?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun" since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
By the standard, this is undefined behavior and therefore a very bad thing. In reality of most programming platforms (across both X86 and several other architectures) this will run fine.
Why? Consider how class functions are implemented in C++. This isn't a virtual function, therefor this can be a static call to a known address.
In x86 assembly, we can see this as
mov A, 0
mov ecx, A
call a__fun
since a__fun requires no instance data, even though it receives a null this pointer, nothing will happen.
Still shitty code and any compiler will scream, but it can run.
The most likely behavior, on most modern computers, is that it will run, and print "fun", because:
C++ doesn't check whether the pointer is NULL before calling the function
fun() is not virtual, so there's no need to refer to a vtable to call fun()
fun() never access any member variables in A so it doesn't need to dereference
the null this pointer.
We can't know what will. Everything can happen, because the program exposes undefined behavior. See Does invoking a member function on a null instance cause undefined behavior?.
I have tried multiple times,all the time output is coming "fun" this is because function fun is independent of instance a. while calling a->fun(); a points to 0 so this is undefined behavior but in most of the compilers there should be no crash.
Three points might help:
1) All Functions are stored in code or text section.
2) Non Virtual functions are resolved at complie time.
3) While calling to member functions of class, we pass current object as this pointer to that function.
Coming to your question , here fun() function is already in memory(code section / text section).
As function fun() is non virtual , it will be resolved at complie time (i.e, for this line it will jump to instruction X at code section with this pointer as NULL).
As no member variable and no virtual function are used/called in fun() function, it is working fine.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I've searched but couldn't find any results (my terminology may be off) so forgive me if this has been asked before. I'm probably using the wrong search keywords.
I understand how vtables are used to handle virtual function calls on a pointer, specifically when "use after free" vulnerabilities come into play.
However, suppose you have a pointer to myclass and you call function myfunction on it when myfunction is NOT implemented virtually?
According to a bit of reading, there is one less fetch, IE instead of fetching the address of the function, then fetching the function, then calling, it is fetched directly.
Howver what confuses me is how this would work if the pointer to myclass had been freed before use.
EDIT: previous paragraph unclear, I am trying to figure out what sort of undefined behaviour might be expected.
Can anyone clear this up for me? If my question is unclear I will clarify...
CodeLion
EDIT:
MyClass *myclass;
free(myclass);
myclass->DoSomething();
Declaration of DoSomething()
void DoSomething{...} // NOT virtual void DoSomething
The short answer is undefined behaviour.
The long answer is based off a typical C++ implementation.
For a non-virtual method, the method is basically a function with an extra parameter that is automatically passed called this: often an atypical calling convention is also used, but that does not matter much.
So foo->method() becomes Foo::method(foo) in effect, and passing a bad (freed) foo is just like passing any other bad/freed parameter.
Relying on this is a bad idea, as the compiler is free to mess with you if you use an invalid this to invoke a non-virtual method.
This is because the address of the function is known at compile time because it can't possible be anything else. Whereas with a virtual function it needs to use the vtable to determine what function to call at runtime.
If the memory where your pointer to the object the method is being called on was already freed then it would just be undefined behavior the same as if it was a virtual function call because the pointer doesn't point to an instance of My class.
Let me make a different interpretation of the OP's question.
If DoSomething is a virtual function, then
myclass->DoSomething () ; // Should be my object
requires the compiler to generate code that examines the object reference by my class and determine what DoSomething to call at run time. If myclass has been deleted
delete myclass ;
then the behavior during this lookup is undefined and the translation process itself provides a point of failure.
If DoSomething is a non virtual function then, this does not require the compiler to implement a procedure to determine which DoSomething to call at run time. The compile might use the exact same process is uses with a virtual function but this would not strictly be necessary. Assuming that the compiler does not generate code for a run time lookup, doing something like
CALL MyClass_DoSomething
then this would not provide a point of failure for an undefined object referenced by myclass. However, the method needs to know which object called it. The compiler is likely to do this as an argument, doing something like for your code:
MOV EAX, myclass
CALL MyClass_DoSomething
or
PUSH myclass
CALL MyClass_DoSomething
This reference to the object has undefined, indeterminate behavior.