#include <iostream>
using namespace std;
class BaseClass
{
public:
BaseClass(int i)
{
data = i;
cout << "_____BaseClass()____" << endl;
}
~BaseClass()
{
data = -99;
cout << "_____~BaseClass()____" << endl;
}
void Fun()
{
cout << "_____Fun()____" << data << endl;
}
int data;
};
int main()
{
BaseClass *b = NULL;
{
BaseClass b1(300);
b = &b1;
}
b->Fun();
return 0;
}
Instance b1 is created in a segment and its life is limited to that segment. I am not able to understand how the data and methods are accessible even after destructor.
C++ as a language gives some guarantees and in many areas leaves things undefined. This means, for some code, the standard doesn't mandate any behaviour and anything, as a result, can be done by the compiler. You're in such a situation.
I am not able to understand how the data and methods are accessible even after destructor.
Once the object is destroyed, accessing it, via a pointer (or something else), is undefined. You being able to access it in some instance of the program doesn't matter. In some other situation you may not be able to - changing the machine, the memory management scheme, or any other environmental factor may make the program crash, hang, etc. i.e. the language doesn't guarantee anything here.
As a general rule, you should never write code that invoke undefined behaviour, unless you're trying to learn something.
Related
This question already has answers here:
Can I access private members from outside the class without using friends?
(27 answers)
Closed 2 years ago.
I have a homework in which:
we have this code:
#include <iostream>
using namespace std;
class Test {
int x;
char y;
public:
Test() :x(0), y(0) { ; }
};
int main() {
Test t;
//Do stuff!
return 0;
}
and without adding getters and setters or using friend class we have to read x and y and also change them.
I searched and found these ways:
if there was a template function in my class I could say:
class Test {
int x;
char y;
public:
Test() :x(0), y(0) { ; }
template<typename T>
void do_something() {//not necessarily void function
//Do some stuff
};
};
class a;
// My specialization.
template <>
void Test::do_something<a>() {
cout << x << endl;
cout << y << endl;
// getting data
x = 5;
y = 'a';
// changing data
cout << x << endl;
cout << y << endl;
// getting data after changes we made
}
int main() {
Test t;
t.do_something<a>();
return 0;
}
and also the method, which I think is this question answer, is using pointers.
like this:
class Test {
int x;
char y;
public:
Test() :x(0), y('0') { ; }
};
int main() {
Test t;
int* ptr = (int*)&t;
cout << "x = " << *ptr << " y = " << (char)*(ptr + 1) << endl;
*ptr--;
//getting data
*ptr = 12;
ptr++;
*ptr = 65;
//changing data
ptr--;
cout << "x = " << *ptr << " y = " << (char)*(ptr + 1) << endl;
//getting data after changes we have made
return 0;
}
or using reinterpret_cast and pointers:
struct pointer {
int x;
char y;
};
class Test {
int x;
char y;
public:
Test() :x(0), y('0') { ; }
};
int main()
{
Test t;
pointer* p = reinterpret_cast<pointer*>(&t);
cout << "X = " << p->x << " Y = " << p->y << endl;
//getting data
p->x = 5;
p->y = 'a';
//changing data
cout << "X = " << p->x << " Y = " << p->y << endl;
//getting data from class after changing them with pointers
return 0;
}
my questions are:
is such thing possible in other object oriented languages?
does this mean access modifiers are useless?
and is there anything we can do to prevent such thing to happen?
(with pointers) why this happen?
I don't understand this one, so I will skip it.
is such thing possible in other object oriented languages?
Consider python. In python making something private is explicitly only an agreement between the author and the user, but nothing prevents a user from accessing private members. Though, they should not. C++ isn't that explicit about saying "if you want you can access private members", but still it is possible with some effort. Nevertheless you should not. C++ does not prevent you from shooting yourself in your foot and accessing private members is one way of doing that. It isn't the case in your example, but typically accessing private members directly will break the object beyond repair.
does this mean access modifiers are useless?
I'll repeat my comment: Is a traffic light useless? I mean when it is red I can still cross the street. Access specifiers are not there to prevent you from doing something wrong by all means, they are to help you to avoid doing something wrong (and if you try hard you can still do something wrong).
and is there anything we can do to prevent such thing to happen?
Declaring a member as private is enough to signal that a user should not access the member directly by any means. If someone wants to break that agreement then they can do it. You cannot prevent a user from doing something wrong. If they want to break your class they can do so. However, it is not your responsibility to guarantee that something broken still works as expected. If a user bypasses access specifiers then they broke the agreement between them and you. Consider you buy a laptop and throw it out of the window from 42th floor. Will you complain to the manufacturer that afterwards the laptop is not working properly anymore? I guess no, instead you will understand that you made something wrong with using your laptop.
PS: Your last two examples are undefined behavior. reinterpret_cast is not a way to cast between arbitrary types magically. The set of allowed casts and what you can do with the results is in fact rather limited (see here). Also a c-style cast enables you do to casts that can be very wrong, without your compiler complaining about it. Thats why they should be avoided in favor of the proper c++ casts (static_cast et al).
Answering your question 4, is there anything we can do to prevent such thing to happen?:
It is indeed a language design problem that code using a class in C++ is typically able to see the inner makeup of a class. A visible, complete class definition is clearly a breach of information hiding. It's necessary though because of the "by-value semantics" of C++ that it inherited from C and which distinguishes it from, say, C# or Java.
One of the consequences is what you describe: That users can easier access object data they are not opposed to. (To be fair, with enough malicious energy that is unpreventable in the general sense no matter the precautions, but knowing the class layout allows you to do so with less "criminal effort", in this case through normal language means. Another, even simpler way which I recall was buried in one large project when it went open source was to simply #define private public before including the header in question.)
A second, more relevant problem is that code which uses objects of that class, or one of its descendants, is too tightly coupled with that class; it knows more than it should or needs to. Any trivial change to the class makes it necessary to recompile all code which includes its definition, directly or indirectly. For large projects with elaborate class hierarchies touching a base class may cause a senseless re-build of the whole project.1
To finally answer your question: The canonical C++ strategy to reduce this coupling are compilation firewalls. You essentially define an interface of pure virtual functions and no data, which should be relatively stable. User code sees only that interface. By that you gain information hiding and the power of polymorphism. But because you cannot directly handle objects any longer but only pointers or references, you lose the advantages of C++'s by-value paradigm (speed, no aliasing).
1 In a job interview in 1998 or so as C++ developer at Star Division, which was developing StarOffice, the original precursor to OpenOffice and LibreOffice, I was asked: "You have a base class, directly or indirectly used throughout the project. Now you would like to add a virtual function to it but avoid recompilation of the whole project, because it would just take too long. Can you do that? How?" The answer is that most implementations probably maintain the virtual functions in a vtable to which you can append without changing the offsets of existing functions (and, of course, without altering the object layout). Obviously, there is no guarantee that the implementation does not generate the vtable backwards, or employs some other mechanism, but in practice that's what you can do.
I was recently asked to predict the output of the following program in an interview:
#include <bits/stdc++.h>
using namespace std;
class a {
public:
int x = 10;
void f() { cout << "hello" << endl; }
void g() { cout << x << endl; }
};
int main() {
a* ptr = new a();
a* ptr1;
a* ptr2 = NULL;
ptr->f();
ptr1->f();
ptr2->f();
ptr->g();
ptr1->g();
ptr2->g();
}
When function f() is called using Null and wild pointers, the output is hello, but when function g() is called using these two pointers, no output is seen on the console. What could be the reason of this behaviour?
The only valid answer - in my opinion - is: The program invokes Undefined Behaviour, so any result is valid. There's no way to tell what an arbitrary compiler will generate and the program in its entirety is invalid.
Additionally, please read Why should I not #include <bits/stdc++.h>?
The behavior of calling methods on uninitialized pointers and null pointers is undefined. That means you can no longer reason about the behavior of the program in any meaningful way. It could literally do anything. For example it could order pizza.
Your program has undefined behavior. Having said that, there is a plausible explanation as to why the calls to f appear to work while the calls to g cause strange behavior.
The functions are many times conceptually translated as:
void mangled_function_for_f(a* const this)
{
cout << "hello" << endl;
}
void mangled_function_for_g(a* const this)
{
cout << this->x << endl;
}
Please note that this not used in f. Hence, the calls to f appear to be OK. Not so with g.
PS Don't count on my explanation on every platform or even the same platform with different compiler options. It's best to avoid code that causes undefined behavior.
I encounter some strange things in C++, but I don't know why?
I have a class like this
header file
class foo
{
public:
void call_foo();
int get_foo();
int get_foo(int val);
};
here is the cpp file
#include "foo.h"
#include <iostream>
using namespace std;
void foo::call_foo()
{
int i = 0;
int j = 33;
cout << i + j << endl;
cout << "Hello, Foo" << endl;
}
int foo::get_foo(int val)
{
int a = 345;
int rc = val + a;
cout << rc << endl;
return rc;
}
int foo::get_foo()
{
int a = 100;
int d = 23;
int rc = a + d;
cout << rc << endl;
return rc;
}
I using code to test as below
int main()
{
int* val = new int[100];
foo* foo_ptr;
foo_ptr = (foo*)val;
foo_ptr->call_foo();
foo_ptr->get_foo();
foo_ptr->get_foo(100);
delete [] val;
return 0;
}
then i compile and execute it.
clang++ foo.cpp main.cpp
Apple LLVM version 5.0 (clang-500.2.79)
os x 10.9
an int pointer convert to an object pointer, then call it's methods, it work! so weird!
Is there anybody know what is going on?
I wrote an article on my blog about why it works in my understood, Thanks all of you!! about object structure, virtual function table. just Chinese version :)
What you are experiencing is called Undefined Behavior.
Undefined Behavior means "anything can happen." Anything here includes the illusion that your code worked, did something you expected it to do, or didn't do something you expected it to do -- like crash.
Code that evokes Undefined Behavior is always faulty code. You cannot rely on Undefined Behavior, if simply for the reason that you cannot predict what will happen.
Now in this case, the reason why calling the methods might appear to work is because in practice an instance of a class doesn't get it's own copy of the code for each of the non-static methods. Instead, there's one copy of the code that is shared between all instances of foo. The pointer to that code never changes, so when you (incorrectly) resolve a pointer-to-foo and then call one of the methods through that pointer, the actual method you expected to call was actually called. This is all still Undefined Behavior however, and you need to fix your code.
It is undefined behaviour and your program is ill-formed. As far as language specification is concerned, anything could happen.
It just happens to appear to work because no member function access any data that would belong to a particular instance of foo objects. All they do is allocate local data and access cout.
It doesn't work, it has undefined behaviour.
However, the functions aren't virtual, and the object has no data members, so it's likely that your program won't actually touch the invalid memory, and so will have the same effect as calling the functions on a valid object.
Your class has no members and no virtual functions so when you call a member function through any arbitrary pointer it will 'work' since you have a statically bound function call and don't do any memory access that would be invalid. Bad things would happen if you tried to call a virtual function or access a member variable.
I'm having trouble understanding why this code works. I've been in the C# world for awhile and wanted to brush up on C/C++ before diving into the new stuff in C++11 like RValue Refs and move semantics.
I'm wondering why this code that I wrote works:
class InnerMember
{
private:
int _iValue;
public:
InnerMember(): _iValue(0) {};
InnerMember(int iValue) : _iValue (iValue) {};
int GetValue(void) { return _iValue; }
int SetValue(int iValue) { _iValue = iValue; }
};
class TestClass
{
private:
InnerMember _objValue;
public:
TestClass() : _objValue(1) {};
void SetValue(int iValue)
{
_objValue.SetValue(iValue);
}
InnerMember& GetRef(void)
{
return _objValue;
}
virtual ~TestClass() { std::cout << "I've been released!" << std::endl; }
};
int main (int argc, char *argv[])
{
TestClass* pobjTest = new TestClass();
std::cout << "Before:" << std::endl;
std::cout << pobjTest->GetRef().GetValue() << std::endl;
pobjTest->SetValue(5);
InnerMember& robjInner = pobjTest->GetRef();
delete pobjTest;
std::cout << "After:" << std::endl;
std::cout << robjInner.GetValue();
return 0;
}
The output is:
Before:
1
I've been released!
After:
5
Press any key to continue...
I thought that this would cause an error, since I access the referenced object InnerMember from TestClass after TestClass has been destroyed. Is there some sort of return value optimization going on? Or is it really returning a copy instead of passing back the reference?
I used GCC to with no optimizations (-O0) and it still ran without an issue.
I also used the -S switch to generate the assembly but my AMD64 knowledge is rusty and the name mangling didn't help.
That is undefined behaviour, which means even the "correct" behaviour could happen. When you delete something in C++, it is not erased from the memory, so accessing it before something else writes over it will sometimes maybe still work.
robjInner is still a reference to some deleted object in memory.
This would lead to undefined behaviour.
After deletion, the reference robjInner has been left dangling. You get back the previous value because no one else claimed that piece of memory yet.
Copied from here
A previously-valid reference only becomes invalid in two cases:
If it refers to an object with automatic allocation which goes out of scope,
If it refers to an object inside a block of dynamic memory which has been freed.
The first is easy to detect automatically if the reference has static scoping, but is still a problem if the reference is a member of a dynamically allocated object; the second is more difficult to assure. These are the only concern with references, and are suitably addressed by a reasonable allocation policy.
You can add a print statement inside InnerMember destructor to see what is going on. You will see InnerMember is destroyed after TestClass and the 5 you get is because no one write to that part of memory yet. But that reference is not valid anymore.
I got some weird problem. I use delete operator inside of class method and I want to know how solve this problem.
This is code:
#include <iostream>
using namespace std;
class A
{
public:
int a;
~A() {
cout << "call ~A()" << endl;
}
void action()
{
/* code here */
delete this; //this line depends on some if statements
/* code here */
}
void test2() {
cout << "call test2()" << a << endl;
}
void test() {
a = 10;
cout << "call test()" << endl;
action();
//how can I check if data is deleted?
test2();
}
};
int main()
{
A* a = new A();
a->test();
}
How can I check if data is deleted by delete operator?
Is it even possible?
Using delete this; is nearly always "bad". There are exceptions, but those are really unusual. Think about what you are trying to do. Most of the time, this means that you should have a wrapper object and an inner object that is created/deleted by the wrapper object.
You can't check if something has been deleted (in a reliable way/portable way). In your particular test-case, you are exercising "undefined behaviour" by "using an object after it has been destroyed", which means you can't really tell what is going to happen. You have to trust the C++ runtime that delete does what it says on the label.
In C++ there are other return values available than void. Therefore your action can return something that indicates if this has been deleted or not.
Note that you should not access any non-static data members or call any non-static member functions after deleteing this. Some people feel it to be difficult to guarantee so they ban delete this altogether.
Note to opponents that C++ FAQ claims that delete this is legal construct and I haven't also found anything forbidding it.