How to avoid "unable to read memory" - c++

I have a struct:
struct a {
a(){};
a(int one,int two): a(one),b(two){};
int a;
int b;
int c;
}
a * b;
cout << b->c;
And sometimes when i want to read (for ex.) c and in debbuger this value is called
'unable to read memory'
Then my program crashed.
And now, how to check that value is readable or not ?
Best Regards.

You haven't initialised the pointer to point to anything, so it's invalid. You can't, in general, test whether a pointer points to a valid object. It's up to you to make sure it does; for example:
a obj(1,2); // an object
a * b = &obj; // a pointer, pointing to obj;
cout << b->a; // OK: b points to a valid object
You can make a pointer null if you don't want it to point to anything. You mustn't dereference it, but it is possible to test for a null pointer:
a * b = nullptr; // or 0, in ancient dialects
if (b) cout << b->a; // OK: test prevents dereferencing
cout << b->a; // ERROR: b is null
But beware that this doesn't help in situations where a pointer might be invalid but not null; perhaps because it wasn't initialised, or because it pointed to an object that has been destroyed.
In general, avoid pointers except when you actually need them; and be careful not to use invalid pointers when you do. If you just want an object, then just use an object:
a b(1,2); // an object
cout << b.a; // OK: b is a valid object

Related

Different behaviour of unique_ptr vs raw pointer

I am struggling to understand the difference in behaviour of a raw pointer and a unique_ptr. I have class A with a variable x and class B with a pointer to an instance of A:
class A
{
public:
int x;
};
A::A(int y) : x(y)
{
}
class B
{
public:
B(A &);
A *p;
};
B::B(A &a)
{
p = &a;
}
This behaves as I would expect:
int main()
{
A a(2);
B b(a);
cout << a.x << " " << b.p->x << endl;
a.x = 4;
cout << a.x << " " << b.p->x << endl;
}
gives
2 2
4 4
Changing the raw pointer to a std::unique_ptr gives a different result:
class A
{
public:
int x;
};
A::A(int y) : x(y)
{
}
class B
{
public:
B(A &);
std::unique_ptr<A> p;
};
B::B(A &a)
{
p = std::make_unique<A>(a);
}
gives
2 2
4 2
Have I fundamentally misunderstood something about unique_ptrs?
make_unique creates a fresh object, one that that unique_pt has exclusive access to. So in the second example you have two objects, not one and when you set change the value of a.x in the first object it doesn't effect the other object held by the unique_ptr.
A unique pointer needs to own whatever it points to. Your code can be made to work - just substituting unique_ptr type and leaving everything else unchanged (no make_unique). But it will have undefined behavior, since you’ll create a unique pointer to an object that is owned elsewhere.
To compare apples to apples, the raw pointer code should read p=new A(a);. That’s what make_unique does.
Try reading the following expression from the smart pointer version:
std::make_unique<A>(a);
"make a unique A from a" (no mention of pointers!)
The result is a unique_ptr, but when reading the expression, read it as making (an object whose type is) the template parameter. The function parameters are parameters to the constructor. In this case, you are making an A object from an A object, which pulls in the copy constructor.
Once you understand that the smart pointer version is making a new A object (and your raw pointer version does not), your results should make sense.
The "unique" in "unique A" might be tricky to understand. Think of it as an object that no one else can lay claim to. It might be a copy of another object, but, taking the role of the unique_ptr, it is your copy, your responsibility to clean up after, and no one else's. Your preciousss, which you will not share (c.f. std::make_shared).
Note that a local variable (like the a in the main function) is the responsibility of the compiler, so it is ineligible to be the object to which a unique_ptr points (or any smart pointer, for that matter).

Why reference is safer than pointer? [duplicate]

This question already has answers here:
Why is a c++ reference considered safer than a pointer?
(9 answers)
Closed 5 years ago.
Hey I'm trying to understand what is the difference between pointer and reference in therm of safety to use, a lot of person say that reference are safer than pointer and it couldn't be null. But for the following code it show that reference could create run-time error but not the pointer :
class A {
public:
A(): mAi(0) {}
void ff() {std::cout << "This is A" << std::endl;}
int mAi;
};
class B {
public:
B() : mBi(0), mAp(NULL) {}
A* getA() const { return mAp; }
void ff(){std::cout << "This is B" << std::endl;}
int mBi;
A* mAp;
};
int main()
{
B* b = new B();
/// Reference part
A& rA = *b->getA();
rA.ff();
std::cout << rA.mAi << std::endl;
/// Pointer part
A* pA = b->getA();
if (NULL != pA)
{
pA->ff();
std::cout << pA->mAi << std::endl;
}
}
This code will crash for "reference part" but not for the "pointer part".
My questions are :
Why we always say that reference are safer than pointers if they could be invalid (as in the previous code) and we can't check for their invalidity?
There is any difference in terms of RAM or CPU consumption between using Pointer or Reference ? (Is it worth to refactor big code to use reference instead of pointer when we can then ?)
References cannot be NULL, that is correct. The reference part of your code however is crashing because you're explicitly trying to dereference a NULL pointer when you try to initialize the reference, not because the reference was ever null:
*b->getA(); // Equivalent to *((A*) NULL)
References can become dangling references though, if you did something like:
int* a = new int(5);
int& b = *a;
// Some time later
delete a;
int c = b + 2; // Ack! Dangling reference
A pointer wouldn't have saved you here, here's the equivalent code using a pointer:
int* a = new int(5);
int* b = a;
// Some time later
delete a;
if(b) { // b is still set to whatever memory a pointed to!
int c = *b + 2; // Ack! Pointer used after delete!
}
Pointers and references are unlikely to make any performance difference, they're probably similarly implemented under the hood depending on your compiler. References might be optimized out completely if the compiler can tell exactly what the reference is bound to.

What happens when I "re-initialize" a pointer

I am currently writing a piece of code in c++ and I came across some behaviour that I don't understand. Let's say that I have a custom class(I'm not sure if it matters what goes on inside the class) and I want to make a pointer to this class:
AliAODEvent* aod;
Now, after I have made this pointer, I want to assign it to a memory location. In the framework that I am using, the object that I want to point to already exists somewhere, so what I did was
AliAODEvent* aod = (This is where the object I want to point to goes);
I realize now that I should just use aod=(Object to point to); But I am curious as to what happened when I tried to essentially "re-initialize" the pointer. Any thoughts?
In C++ you have declaration and initialisation.
int x; // Declaration
x = 10; // Initialisation
Declaring a variable means asking the operating system to allocate a place in memory for it. Initialising a variable means setting the value at that memory address for the first time. You can do both at once:
int x = 10; // Declares x, then initialises it to 10
In C++ it is not allowed to declare a variable more than once:
int x; // Declares x
int x; // Tries to declare another variable also called x, fails (ERROR)
However, you CAN declare two variables with the same name as long as they are in different scopes:
#include <iostream>
int x = 10;
int main()
{
int x = 20;
{
int x = 30;
std::cout << x << ", " << ::x << std::endl; // Prints '30, 10'
}
std::cout << x << ", " << ::x << std::endl; // Prints '20, 10'
return 0;
}
{} denotes new scope, and :: denotes global scope. So you can specify global scope, or you can use local scope, but you can't use anything else with the same name.
In C++, the statement
AliAODEvent* aod = (This is where the object I want to point to goes);
means "please create for me a new variable called aod of type AliAODEvent* and assign it a particular variable." On the other hand, the statement
aod = (This is where the object I want to point to goes);
means "find an existing variable called aod and assign it to point to a new location." The distinction here is that, by including the name of the type, C++ thinks you're giving a declaration that introduces a new variable, rather than an assignment statement that takes an existing variable and changes where it points. This is just how the language is designed.
The reason this second one works while the first doesn't is that you're ultimately trying to take something that exists and change it, which means you should not be providing a declaration. Generally speaking, you only should include the type of a variable in a statement if you're declaring that variable and otherwise should just use its name.
You are not reinitializing the pointer in that case, but trying to create a pointer of the same name, which would be an error, unless it was in a different scope block.
ie:
AliAODEvent* aod;
{
AliAODEvent* aod = (something)
}
In that case, the aod variable would be ok (although might show a warning) as would be a different vaiable, which would no longer be there once the scope of it (the '}') ended.
The following code:
A* aod = &x;
A* aod = &y;
is declaring two variables, and is ill-formed. It should be rejected by most compilers but with the right settings some compilers may let it through.
What happened here is that the compiler created storage for the first variable and stored the address of x into it. Then it created additional storage for a second variable and hid the original variable.
At this point, the program is storing both the value of x and y in different memory locations, but you can only refer to the second aod until it goes out of scope.
This is usually called "shadowing" and is legal only between scopes:
#include <iostream>
struct A {};
A a, b, c;
A* ptr = &a;
void report(A* p) {
std::cout << (void*) &a << ", " << (void*) &b << ", " << (void*) &c
<< ": " << (void*) p << "\n";
}
int f() {
std::cout << "f() ";
report(ptr);
}
int main() {
report(ptr);
if (ptr != nullptr) {
A* ptr = &b;
report(ptr);
if (ptr != nullptr) {
A* ptr = &c;
f();
report(ptr);
}
report(ptr);
}
report(ptr);
}
Live demo: http://ideone.com/LBFWFT
Also, be aware that pointers are not smart.
A* aod = new A;
aod = new A;
This allocates two As but never frees the first one, because we never tell it to, we simply overwrite the value. The compiler does not keep a track of when a dynamic object is no-longer referenced.
int main() {
A* aod = nullptr;
if (aod == nullptr) { // start new scope
A x;
aod = &x;
} // end scope, `x` is destroyed.
use(aod);
}
This code introduces a bug: aod points to the address of x, but x is destroyed when it goes out of scope at the } so this pointer is dangling and references invalid memory.
In giving the pointer an address to an existing location, you don't want to use the type specifier to the left of it again, since that variable already exists (that's declaring a variable). You won't be able to declare a new variable aod again while you are in the scope of the first aod.
Additionally, to be clear, saying aod=(Object to point to); is only correct if you have the address of the object after the assignment operator, not the object itself. You assign the address of an object to a pointer by using the & operator before the name of another object to obtain its address:
Object* objectPointer = &existingObject; //point objectPointer to the address of existingObject
Or, by a method,
Object* objectPointer = method()
where method() has a return type of Object* (pointer to an Object type).
You can also create a new object on the heap using the new operator:
Object* objectPointer = new Object("args");
which must be deleted with the delete operator when you're done with it.
delete objectPointer;
Remember that just because a pointer falls out of scope and stops existing, doesn't mean that the memory it points to does.

create an instance for a pointer in other scopes

I have two methods to create an instance for a pointer.
But one of them will fail.
class A {
public:
int num;
};
void testPointer1(A* a){
a = new A();
a->num = 10;
}
A* testPointer2(){
A* a = new A();
a->num = 10;
return a;
}
void testPointer() {
A* a1 = NULL;
testPointer1(a1); // this one fails
//cout << a1->num << endl; // segmentation fault
A* a2 = NULL;
a2 = testPointer2();
cout << a2->num << endl;
}
why is testPointer1 wrong?
The syntax is valid, but it doesn't do what you want because testPointer1() is operating on a copy of the pointer, not the actual pointer itself. So when you assign the address to the newly allocated object, it gets assigned to the copy, not to the original a1 pointer.
Because of this, the address is lost and you get a memory leak. Also, since the original a1 pointer was never modified in the first place, you attempted to dereference a null pointer, which is a bad thing.
I'd say testPointer2() is the better way to do it, but if you want testPointer1() to work, try this:
void testPointer1(A*& a)
{
a = new A();
a->num = 10;
}
The parameter type indicates "a reference to a pointer to A." That way, instead of a copy of the pointer being passed, a reference to the original pointer will be passed. A C++ reference is an alias to another object. So whatever you do on the alias, it gets performed on the original object.
Extra notes:
Note that the parentheses in new A(); are actually significant and their presence or absence makes a difference.
Also note that you must manually delete all new'ed objects after you're done with them, or you will get a leak. Typically you would wrap the pointer in its own class and implement RAII or use a smart pointer such as Boost's smart pointers or auto_ptr, for proper memory management and exception safety.
If you're going to set the value of num on initialization, why not create a constructor?
class A
{
public:
A(int n) : num(n) {}
int GetNum() const { return num; }
private:
int num;
};
void testPointer1(A*& a)
{
a = new A(10);
}
A* testPointer2()
{
return new A(10);
}
// auto_ptr example, see link in second note above
std::auto_ptr<A> testPointer3()
{
return auto_ptr<A>(new A(10));
}
The testPointer1 functions works on a copy of the provided pointer : modifications to a in testPointer1 are not reflected to the caller.
It's exactly like in this simpler example :
void testInt1(int i)
{
i++;
}
void testInt()
{
int i = 0;
testInt1(i);
// i is still 0
}
If you want the change in testInt1 to be reflected to the caller, you have to pass either a pointer or reference to i (and not just the value of i). The same solution can be applied to your specific case, though one could argue that pointers to pointer and references to pointer are not really a best practice.
Is this homework ?
This seems to be obvious:
formal parameters are saved on the stack & restored after method/function call.
then whatever f(type x), manipulating x inside the function/method won't change it's value outside of the function.
even if type is a pointer type.
the only way to make x change inside a function is to tell it is modifiable through references or pointer to type.
in your case :
A* a1 =NULL
call to your method won't change value of a1 outside of testPointer1
so a1 will still be NULL after the call.

boost::shared_ptr question. Why does this work?

In experimenting with this question I created an example that I utterly do not understand. In particular, it highlights my misunderstanding of pointers, references, and the boost::shared_ptr.
int& r = *(new int(0));//gratuitous pointer leak, got to initialize it to something
{
boost::shared_ptr<int> sp(new int(100));
r = *sp;
cout << "r=" << r << endl;
}
cout << "r=" << r << endl << endl;
int* p;
{
boost::shared_ptr<int> sp(new int(100));
p = &*sp;
cout << "*p=" << *p << endl;
}
cout << "*p=" << *p << endl;
Running this code gives an output something like this:
r=100
r=100
*p=100
*p=13
Why does the reference survive the death of the shared_ptr but the pointer does not?
There's a problem in the answers here in that there seem to be two diametrically opposed and contradictory solutions and no consensus upon which is the truth. I would like the ability to use a reference after a shared_ptr is deleted, but if it's invalid I really need to understand this.
Perhaps someone can post a simple example that demonstrates the undefined behavior in the reference.
Because r = *sp; does not do what you think it does. It assigns to the referent, that is, to the anonymous int object you created on the heap in line 1. You cannot reseat references in C++.
Here is what the standard says about evaluating reference expressions:
If an expression initially has the type "reference to T",
the type is adjusted to T prior to any further analysis.
The expression designates the object or function denoted by the reference,
and the expression is an lvalue or an xvalue, depending on the expression.
So you see, there is no way to get to "the reference itself". It simply does not exist in C++.
Maybe this code will make it clearer:
int a = 42;
int b = 97;
int&r = a; // r is just an alias (another name) for a
r = b; // assigns b to a (does NOT bind r to b, that's impossible in C++!)
After executing the last line, both a and b contain 97, because r = b really means a = b.
p is undefined, r is a copy
int& r = *(new int(0));
{
boost::shared_ptr<int> sp(new int(100));
r = *sp; // copy
cout << "r=" << r << endl;
}
cout << "r=" << r << endl << endl;
int* p;
{
boost::shared_ptr<int> sp(new int(100));
p = &*sp;
cout << "*p=" << *p << endl;
}
cout << "*p=" << *p << endl; // Undefined, pointer points to deleted int
In the second case, your int-object is destructed. In the first case it is not.
In the first case, you create a new int-object with new in the outer scope. In the inner scope, you create a second int-object, for which you also create a shared_ptr, which then owns the int-object. This shared_ptr runs out of scope when you close the inner scope, it therefore gets destructed. The shared_ptr destructor will also destruct the object it refers to, because no other shared_ptr (that was created from the original one) refers to your int object anymore. That's all alright. However, in the middle of that scope you re-assign the value of r to that of *sp (100). You therefore save the value of *sp, before sp gets destructed, into r.
Note: it's certainly questionable style to create an int object the way you do it in your first line of code. If you don't explicitly delete that int object, this is a memory leek. The way to destruct it would be delete &r which looks really ugly, especially because the symbol r afterwards still refers to the, now deleted, int object. DON'T DO THIS!
In the second case you create an int pointer at the beginning, but no int object. The inner scope is almost the same as before, except that this time you do not save the value of your new int object into the outer-scope variable (p), but you save the address of the int object! As the int object gets destructed at the end of the inner scope (for the same reason as previously), p no longer points to an existing int object, but to a place in memory which formerly once hold an int object. The value you get from *p is undefined: you might still get 100, you could get any other value, and you might even crash your programme here (Segmentation fault) as you dereference a memory location you no longer hold.
So to summarise, and answer your final question:
The reference survives, because it still refers to an existing object. The pointer does not, because it points to a no longer existing object.