I'm trying to understand pointers so I did this code:
#include<iostream>
using namespace std;
struct teste{
int a;
bool b;
};
void say (struct teste* a) {
cout << (*a).a << (*a).b << "\n";
}
int main() {
teste* e;
(*e).a=2;
(*e).b=0;
say(e);
}
which gives me Segmentation Fault
but the following:
#include<iostream>
using namespace std;
struct teste{
int a;
bool b;
};
void say (struct teste* a) {
cout << (*a).a << (*a).b << "\n";
}
int main() {
teste e;
e.a=2;
e.b=0;
say(&e);
}
I know that the second one is prefered but why the first one will not work? I think I did everything all right.
teste* e;
(*e).a=2;
(*e).b=0;
This gives you segmentation fault because pointer e is not initialized - it doesn't point to valid memory.
When you initialize pointer with some address say y - and then apply dereference operator, you tell it to retrieve value from the memory address y which you assigned to it. In your case, no address has been assigned to it, so you can't dereference it.
Make it point to a teste object, then you can dereference it.
Imagine you ask me "where is the airport"? I offer to write the address of it on a sticky note for you.
On the note I write:
airport
This is not very helpful, is it?
teste* e;
this says "declare a variable, e, such that it holds the address of an instance of teste in memory".
But you haven't provided an actual instance of teste for it to point to; you didn't actually assign the address of something to it.
int main() {
teste instance;
teste* e = &instance;
e->a = 2;
(*e).b = 0; // equivalent to e->a
say(e);
}
The line
teste* e = &instance;
says "declare a variable, e, such that it holds the address in memory of a teste struct, and let that address be the address-of instance (&instance)".
We could also have written
teste* e;
e = &instance;
But it's better practice to try and always initialize your variables at the time of declaration, if you can.
The -> operator is more-or-less syntactic sugar for (*e). -- it accesses through (dereferences) the pointer.
e->a
// is equivalent to
(*e).a
Where . is the member-of -> is the member-through.
Note that . and -> are distinct operators, which will become important later in your understanding of the language.
In this example, instance is a local variable and so is created on the stack. This means that when the scope ends it will be destroyed/go away.
If you need instance to stick around longer, or it is very large, you can allocate it from the "heap".
int main() {
teste* e = new teste;
e->a = 2;
e->b = 0;
say(e);
delete e;
}
Explaining new and delete is probably beyond the scope of answering this question, I leave it to you to learn about them and their use.
In the first example you declare a pointer, but that pointer points to nothing. So you get the seg. fault. You should assing a value to that pointer, being an address of an instance of teste, either declared or created in memory using new() or malloc()
You never actually allocated any memory for e. You can either declare it on the stack, then pass it as a pointer by taking it's address using operator &
int main() {
teste e;
e.a=2;
e.b=0;
say(&e);
}
or declare it on the heap using new, then delete it when you're done.
int main() {
teste* e = new teste;
e->a=2;
e->b=0;
say(e);
delete e;
}
Related
A class type called "Pair" has already been defined for you. You need to write a function called pairFactory that creates an instance of Pair on the heap. Do not create the object on the stack. Then, your function needs to return a pointer to that created object.
I have written the code for pairFactory. It seems to run, but I get an InfraError.
Please help me find my mistake.
Also, I need to create the object in heap memory.
#include <iostream>
// This class Pair has already been defined for you.
// (You may not change this definition.)
class Pair {
public:
int first, second;
void check() {
first = 5;
std::cout << "Congratulations! The check() method of the Pair class \n has executed. (But, this isn't enough to guarantee \n that your code is correct.)" << std::endl;
}
};
Pair *pairFactory() {
//
Pair P;
P.check();
// (You can use as many lines as you want.)
return &P;
}
// Your function should be able to satisfy the tests below. You should try
// some other things to convince yourself. If you have a bug in this problem,
// the usual symptom is that after you submit, the grader will crash with a
// system error. :-)
int main() {
Pair *p;
p = new pairFactory();
// This function call should work without crashing:
p->check();
// Deallocating the heap memory. (Assuming it was made on the heap!)
delete p;
std::cout << "If you can see this text, the system hasn't crashed yet!" << std::endl;
return 0;
}
You've got it backwards. Your factory needs to allocate on the heap. What you're doing is returning the address of a function-local object that doesn't exist anymore.
Pair *pairFactory() {
return new Pair;
}
And then in your main function:
Pair *p = pairFactory();
You return reference to local variable here.
Pair *pairFactory() {
Pair P;
P.check();
return &P; // Dangling pointer
}
So you have dangling pointer, once you leave the function.
You have to call new.
Pair *pairFactory()
{
return new Pair{};
}
main may look like:
int main() {
Pair* p = pairFactory();
// This function call should work without crashing:
p->check();
// Deallocating the heap memory. (Assuming it was made on the heap!)
delete p;
std::cout << "If you can see this text, the system hasn't crashed yet!" << std::endl;
}
Better to use smart pointer to not have to manage memory yourself:
std::unique_ptr<Pair> pairFactory()
{
return std::make_unique<Pair>();
}
int main() {
auto p = pairFactory();
p->check();
std::cout << "If you can see this text, the system hasn't crashed yet!" << std::endl;
}
You did exactly as you were told not to do:
Pair *pairFactory() {
Pair P; // <----- creates an instance of Pair on the stack
…
}
The intention of this exercise likely was to test your knowledge on the new operator. See here https://en.cppreference.com/w/cpp/memory/new/operator_new
The function
Pair *pairFactory() {
return &P;
}
returns a pointer to memory on the local stack, which is destroyed / invalid as soon as it returns to main().
The issue with your code is that it returns a pointer that points to nothing as P only exists till the value of p is returned, as stored in heap memory. Using new keyword will allocate the memory in heap and will return a pointer to the value.
Pair *pairFactory() {
Pair P;
P.check();
return &P;
}
I want to understand what happens, if we allocate dynamic memory inside a static function? Each call to static function returns the same memory, or every time a new memory is created??
For example-
class sample
{
private:
static int *p;
public:
static int* allocate_memory()
{
p = new int();
return p;
}
};
int* sample::p=NULL;
int main()
{
int *p= sample::allocate_memory();
int *q = sample::allocate_memory();
cout << p << " " << q << endl;
if (p== q)
cout << "we are equal";
}
In this program both memory locations inside main() are different. if we move static int *p; inside allocate_memory() function, like static int *p = new int; both memory location will come same.
I want to understand what is the difference. static is always static, weather it is inside class or inside function, then why behavior is different??
Devesh
One of the issues here is that the keyword static means a lot of different things in C++ depending on context. You have stumbled upon two of these.
If a member variable is declared static, that means the class itself has one copy of this variable which is shared between all instances.
If a local variable in a function is static, it means the value of that variable persists in-between function calls. It always refers to the same location in memory, even between calls (or in recursive calls). For such a variable, the initializer is only only executed the first time the function is entered.
So, if you've tried this:
static int* allocate_memory()
{
static int p = new int();
return p;
}
the assignment to a new int() will only be called the first time you call the function. This is because, when written as part of the variable declaration, it is an initializer. If, however, you would do this:
static int* allocate_memory()
{
static int p;
p = new int();
return p;
}
Then, you would see the same behaviour as in your other case.
Every time you call allocate_memory, a new int is created. p is static, but what it points at will change.
To return a pointer to the same object every time:
static int* allocate_memory()
{
if(!p)
{
p = new int();
}
return p;
}
In your main method, p and q will be different regardless of how allocate_memory works, as they are two different pointers. If you de-reference p and q, you will compare what they are pointing to:
if(*p == *q)
{
cout << "Equal";
}
I have just started to study C++, and right now I am working with pointers. I cannot understand why the following thing is happening.
So, say I have two classes A and B. A has an integer field (int valueA) and B has a pointer field (to A), A *a. Below I have shown both classes.
class A{
A::A(int value){
valueA = value;
}
void A::displayInfo (){
cout<<A<<endl;
}
}
class B{
B::B(){
a=0;
}
void B::printInfo (){
a -> displayInfo(); //Segmentation fault
}
void B::process(){
A new_A = A(5);
a = &new_A;
new_A.displayInfo(); //correct output
a -> displayInfo(); //correct output
}
}
Now when in my main class I do the following: create an instance of the B class and call the process() and print() functions. In the output I get: 5(which is correct), 5(which is correct) and Segmentation fault. Can anyone please help me understand why this is happening? According to my current understanding of pointers, I am doing the correct thing?
int main(void)
{
B b_object();
b_object.process();
b_object.print();
}
Just to make this clear, I have an A.h and B.h file where I declare "int valueA;" and "A *a;" respectively. And I know this can be done much easier without pointers, but I am trying to learn how pointers work here :D
A new_A = A(5);
a = &new_A;
Here you create new_A which is local to process and assign its address to a. When the process function ends, new_A goes out of scope and is destroyed. Now a points at an invalid object.
The real solution here is to not use pointers like this, but if you really have to, to have something last beyond the end of the function you need to dynamically allocate it. Do this with a = new A(5);. You need to make sure that you delete a; at some later point in the program, otherwise the dynamically allocated memory will be leaked.
a is assigned to a local variable in process() therefore not valid in printInfo()
The variable a is local to your methods - declare it at the class level
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Can a local variable's memory be accessed outside its scope?
Is there worrying thing to do a code such (getIDs() returns a pointer):
class Worker{
private:
int workerID;
int departID;
int supervisorID;
public:
Worker()
{
workerID=0;
departID=0;
supervisorID=0;
name="anonymous";
workerAddress="none";
}
void setIDs(int worker, int depart, int supervisor)
{
workerID=worker;
departID=depart;
supervisorID=supervisor;
}
int* getIDs()
{
int id[3];
id[0]=workerID;
id[1]=departID;
id[2]=supervisorID;
return id;
}
};
And then, use it such:
Worker obj;
obj.setIDs(11,22,33);
cout<<(*obj.getIDs())<<endl;
cout<<++(*obj.getIDs())<<endl;
cout<<++(++(*obj.getIDs()))<<endl;
I am wondering about that because the compiler shows:
Warning 1 warning C4172: returning address of local variable or
temporary
Your int id[3] is allocated on a stack and gets destroyed when your int* getIDs() returns.
You're return a pointer to a variable that gets destroyed immediately after getIDs() returns. The pointer then becomes dangling and is practically useless as doing anyting with it is undefined behaviour.
Suppose you defined your class like this:
class Worker{
private:
int IDs[3];
public
// ...
int* getIDs() { return IDs; }
};
This partially solves your problem, as the pointer remains valid as long the Worker object is in scope, but it's still bad practice. Example:
int* ptr;
while (true) {
Worker obj;
obj.setIDs(11,22,33);
ptr = obj.getIDs();
cout << *ptr; // ok, obj is still alive.
break;
} // obj gets destroyed here
cout << *ptr; // NOT ok, dereferencing a dangling pointer
A better way of solving this is to implement your custom operator << for your class. Something like this:
class Worker {
private:
int workerID;
int departID;
int supervisorID;
public:
// ...
friend ostream& operator<<(ostream& out, Worker w);
};
ostream& operator<<(ostream& out, const Worker& w)
{
out << w.workerID << "\n" << w.departID << "\n" << w.supervisorID;
return out;
}
Even if this would work, it wouldn't be good practice to do it this way in c++ unless there is some profound reason why you want pointers to int. Raw c-syle arrays are more difficult to handle than, for instance, std::vectors, so use those, like
std::vector<int> getIDs(){
std::vector<int> id(3);
id[0]=workerID; id[1]=departID; id[2]=supervisorID;
return id;
}
If you're worried about the overhead: this is likely to be optimized away completely by modern compilers.
A local (also caled automatic) variable is destroyed once you leave the function where it is defined. So your pointer will point to this destroyed location, and of course referencing such a location outside the function is incorect and will cause undefined behaviour.
The basic problem here is that when you enter a function call, you get a new frame on your stack (where all your local variables will be kept). Anything that is not dynamically allocated (using new/malloc) in your function will exist in that stack frame, and it gets destroyed when your function returns.
Your function returns a pointer to the start of your 3-element-array which you declared in that stack frame that will go away. So, this is undefined behavior.
While you may get "lucky/unlucky" and still have your data around where the pointer points when you use it, you may also have the opposite happen with this code. Since the space is given up when the stack frame is destroyed, it can be reused - so another part of your code could likely use the memory location where your three elements in that array is stored, which would mean they would have completely different values by the time you dereferenced that pointer.
If you're lucky, your program would just seg-fault/crash so you knew you made a mistake.
Redesign your function to return a structure of 3 ints, a vector, or at the very least (and I don't recommend this), dynamically allocate the array contents with new so it persists after the function call (but you better delete it later or the gremlins will come and get you...).
Edit: My apologies, I completely misread the question. Shouldn't be answering StackOverflow before my coffee.
When you want to return an array, or a pointer rather, there are two routes.
One route: new
int* n = new int[3];
n[0] = 0;
// etc..
return n;
Since n is now a heap object, it is up to YOU to delete it later, if you don't delete it, eventually it will cause memory leaks.
Now, route two is a somewhat easier method I find, but it's kind of riskier. It is where you pass an array in and copy the values in.
void copyIDs(int arr[3] /* or int* arr */)
{
arr[0] = workerID;
/* etc */
}
Now your array is populated, and there was no heap allocation, so no problem.
Edit: Returning a local variable as an address is bad. Why?
Given the function:
int* foo() {
int x = 5;
return &x; // Returns the address (in memory) of x
} // At this point, however, x is popped off the stack, so its address is undefined
// (Garbage)
// So here's our code calling it
int *x = foo(); // points to the garbage memory, might still contain the values we need
// But what if I go ahead and do this?
int bar[100]; // Pushed onto the stack
bool flag = true; // Pushed onto the stack
std::cout << *x << '\n'; // Is this guaranteed to be the value we expect?
Overall, it is too risky. Don't do it.
#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
using namespace std;
class Teste {
private:
Teste *_Z;
public:
Teste(){
AnyNum = 5;
_Z = NULL;
}
~Teste(){
if (_Z != NULL)
DELETE(_Z);
}
Teste *Z(){
_Z = new Teste;
return _Z;
}
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
int AnyNum;
};
int main(int argc, char *argv[]){
Teste *b = new Teste, *a;
a = b->Z();
cout << "a->AnyNum: " << a->AnyNum << "\n";
b->Z(new Teste);
cout << "a->AnyNum: " << a->AnyNum << "\n";
//wdDELETE(a);
DELETE(b);
return 0;
}
I would like to know if there is a memory leak in this code
it works ok, the *a is set twice and the AnyNum prints different numbers on each cout <<
but I wonder what happened to the _Z after the setter(new Teste), I don't have much knowledge in pointers/references yet, but for the logic I guess it is being swapped for the new variable
if it is leaking, is there anyway to accomplish this without having to set a to _Z again?
because the address didn't change, just the direct memory allocated
I was going to use *& instead of just pointers, but would it make difference?
There is a memory leak on this line:
b->Z(new Teste);
because of the definition of the function:
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
It looks like Z without arguments was supposed to be a getter and with arguments a setter. I suspect you meant to do:
void Z(Teste *value){
value->AnyNum = 100;
_Z = value;
}
(note the third line) That is, assign the pointer "value" to the pointer "_Z" instead of copy what value pointed at over what Z pointed at. With that, the first memory leak would be resolved, but the code would still have one since _Z could have been holding a pointer. So you'd have to do:
void Z(Teste *value){
value->AnyNum = 100;
delete _Z; // you don't have to check for null
_Z = value;
}
As mentioned in another comment, the real solution is to use smart pointers. Here's a more modern approach to the same code:
using namespace std;
class Teste {
private:
boost::shared_ptr<Teste> Z_;
public:
Teste() : AnyNum(5), Z_(NULL)
{ }
boost::shared_ptr<Teste> Z()
{
Z_.reset(new Teste);
return Z_;
}
void Z(boost::shared_ptr<Teste> value)
{
value->AnyNum = 100;
Z_ = value;
}
int AnyNum;
};
int main(int argc, char *argv[]){
boost::shared_ptr<Teste> b = new Teste, a;
a = b->Z();
cout << "a->AnyNum: " << a->AnyNum << "\n";
b->Z(boost::shared_ptr<Teste>(new Teste));
cout << "a->AnyNum: " << a->AnyNum << "\n";
return 0;
}
Yes there is:
void Z(Teste *value)
{
value->AnyNum = 100;
*_Z = *value; // you need assignment operator
}
The compiler-generated assignment operator will not make a deep copy, instead it will make a shallow copy. What you have to do is to write a suitable assignment operator (and possibly a copy constructor) for Teste. Also, you don't have to check if a pointer is NULL before deleting it:
~Teste()
{
// no need for checking. Nothing will happen if you delete a NULL pointer
if (_Z != NULL)
DELETE(_Z);
}
You've got another problem: _Z is not an identifier you should be using. In general, it's best to avoid leading underscores, and in particular double underscores or underscores followed by a capital letter are reserved for the implementation.
What a mess!
The whole program is very hard to read because of the choice of identifier names to start with:
#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
I find that very ugly.
When using classes it seems very un-nessacery. You could use it where a variables is going out of scope but it is a waster of time in the destructor. I think it would be asier to wrap the code in some smart pointer:
class Teste
{
private:
Teste *_Z;
public:
Teste()
~Teste() // Delete the _Z pointer.
Teste *Z();
void Z(Teste *value);
};
Ok. You have a pointer member that you delete in the destructor.
This means you are taking ownership of the pointer. This means that the ule of four applies (similar to the rule of three but applicable to ownership rules). This means you basically need to write 4 methods or the compiler generated versions will mess up your code. The methods you should write are:
A Normal (or default constructor)
A Copy constructor
An Assignment operator
A destructor.
Your code only has two of these. You need to write the other two.
Or your object should not take ownership of the RAW pointer. ie. use a Smart Pointer.
Teste *_Z;
This is not allowed.
Identifiers beginning with an underscore and a capitol letter are reserved.
You run the risk of an OS macro messing up your code. Stop using an underscore as the first character of identifiers.
~Teste(){
if (_Z != NULL)
DELETE(_Z);
}
This is not needed. Asimple delete _Z would have been fine.
_Z is going out of scope because it is in the destructor so no need to set it to NULL.
The delete operator handles NULL pointers just fine.
~Test()
{ delete _Z;
}
Teste *Z(){
_Z = new Teste;
return _Z;
}
What happens if you call Z() multiple times (PS putting the * next to the Z rather than next to the Teste make it hard to read).
Each time you call Z() the member variable _Z is given a new value. But what happens to the old value? Basically you are leaking it. Also by returning a pointer to an object owned
inside Teste you are giving somebody else the opportunity to abuse the object (delete it etc). This is not good. There is no clear ownership indicated by this method.
Teste& Z()
{
delete _Z; // Destroy the old value
_Z = new Teste; // Allocate a new value.
return *_Z; // Return a reference. This indicates you are retaining ownership.
// Thus any user is not allowed to delete it.
// Also you should note in the docs that it is only valid
// until the next not const call on the object
}
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
You are copying the content of a newly constructed object (that contains a pointer) into another dynamically created object!
What happens if _Z had not been allocated first. The constructor sets it to NULL so there is no guarantee that it has a valid value.
Any object you allocate you should also delete. But here value is dynamically allocated passed into Z but never freed. The reason you get away with this is because the pointer is c
opied into _Z and _Z is deleted when its destructor is destroyed.
Teste *b = new Teste, *a;
That's really heard to read. Don;t be lazy write it out properly.
This is considered bad style and you would never get past any code review with that.
Teste* b = new Teste;
Teste* a; // Why not set it to NULL
a = b->Z();
Getting ab object for a. But who was destroying the object a or b?
b->Z(new Teste);
It just gets too convoluted after that.
(I tried to add this as a comment but that screws up the code..)
I'd aslo strongly suggest not to use
#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
but instead something like
struct Deleter
{
template< class tType >
void operator() ( tType*& p )
{
delete p;
p = 0;
}
};
usage:
Deleter()( somePointerToDeleteAndSetToZero );
(not really an answer, but a comment wouldn't do)
The way you defined your macro is prone to a subtle errors (and the fact that no one spotted it so far just proves it). Consider your code:
if (_Z != NULL) // yes, this check is not needed, but that's not the point I'm trying to make
DELETE(_Z);
What happens after the preprocessor pass:
if (_Z != 0)
delete _Z; _Z = 0;
If you still have trouble seeing it, let me indent it properly:
if (_Z != 0)
delete _Z;
_Z = 0;
It's not a big deal, given that particular if condition, but it will blow-up with anything else and you will spend ages trying to figure out why your pointers are suddenly NULL. That's why inline functions are preferred to macros - it's more difficult to mess them up.
Edit: ok, you used comma in your macro definition so you are safe... but I would still say it's safer to use [inline] function in this case. I'm not one of the do-not-use-macros-ever guys, but I wouldn't use them unless they are strictly necessary and they are not in this case
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
and
b->Z(new Teste);
creates a memory leak
the 'new Teste' never gets deleted, instead what you are doing is allocating a new object as parameter, then copying whatever is in there using *_Z = *value but the object is not deleted after the call.
if you were to write
Test* param - new Teste;
b->Z(param)
delete param;
it would be better
of course most would use boost::shared_ptr or something similar to avoid caring about delete and such