#include<iostream>
#include <string>
using namespace std;
class Human
{
private:
int *age;
string *name;
public:
Human(string p_name, int value)
{
*name = p_name;
*age = value;
cout <<"Name of Person is "<<*name <<" and age is "<<*age<<endl;
}
~Human()
{
delete name;
delete age;
cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl;
}
void display()
{
cout << "The name is "<<*name <<" and age is "<<*age<<endl;
}
};
int main()
{
int age = 24;
string name = "CODY";
Human cody(name,age);
cody.display();
}
It is not printing anything.... What is happening can somebody explain it please.... Is it due to I implemented pointer variable incorrectly...Why is it incorrect please tell me then and what will be the alternative solution
CodePudding user response:
There are several mistakes in your given program as explained below.
Mistake 1
First you need to make sure that the data members age
and name
point to some variables of appropriate type. Then only you can dereference them. Since you're dereferencing the pointers that don't point to objects of appropritate types, you have undefined behavior in your program.
Human(string p_name, int value)
{
*name = p_name; //Undefined behavior because name doesn't point to an std::string object
*age = value; //Undefined behavior because age doesn't point to an int object
cout <<"Name of Person is "<<*name <<" and age is "<<*age<<endl;
}
Mistake 2
Second you can use delete
when you have allocated memory using new
. And since you have not allocated any memory using new
, it is incorrect to use delete
.
~Human()
{
delete name; //not valid
delete age; //not valid
cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl; //undefined behavior as explained in mistake 3
}
Mistake 3
Third you're dereferencing the pointers age
and name
just after you used delete
on them. This again leads to undefined behavior.
cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl; //undefined behavior because you just used `delete` on the pointers and also because they don't point to objects of the appropriate type
Better would be to use smart pointers that will take care of memory management for you. That is, when we use smart pointers we don't have to manually use new
and delete
.
Just so that you can see how to correct the current 2 mistakes you can refer to the below given modified example:
//this uses constructor initializer list
Human(string p_name, int value): age(new int(value)), name(new std::string(p_name))
{
cout <<"Name of Person is "<<*name <<" and age is "<<*age<<endl;
}
//destructor
~Human()
{
if (name != nullptr && age!=nullptr)
{ //check that
delete name;
delete age;
cout<<"delete used successfully"<<endl;
}
else
{
cout<<"delete not used"<<endl;
}
}
CodePudding user response:
why pointer variable inside private class can't point to outside variable of class
The premise of your question is faulty. A private member variable can point to outside of the class.
Human(string p_name, int value) { *name = p_name; *age = value;
You didn't initialise the pointers, so indirecting through them results in undefined behaviour. Don't do this.
cout << "The name is "<<*name <<" and age is "<<*age<<endl;
Here, you indirect through the invalid pointers and the behaviour of the program is undefined.
delete name; delete age; cout<<"Destructor release all memory So now name is "<<*name << " and age is "<<*age<<endl;
Even if the pointers weren't invalid, it would be wrong to delete them. You didn't create any objects with allocating new
, so there is nothing to delete. Deleting the pointers that weren't returned by allocating new
will result in undefined behaviour. Don't do this.
Furthermore, even if delete
had been valid, that would invalidate the pointers, and the successive indirection through the newly invalidated pointers in the cout
statement would result in undefined behaviour. Don't do this either.
Solution: Remove the delete
lines.
A solution where the class points to variables outside of the class: In order to refer to an object outside of a function, you need to use indirection. You can use a pointer parameters for example, and initialise the members to point to the same objects:
Human(string* p_name, int* value)
: name(p_name), age(value)
{}
// example usage:
Human cody(&name, &age);
Note that storing pointers in members is precarious because you must be aware of the relative lifetimes of the pointed objects, and the object containing the pointers. You must be sure that the pointers don't outlive the pointed objects.
Considering the problems of the referential design of your class, I urge you to consider using values instead. This would likely be more useful class in general:
struct Human {
std::string name;
int age;
void display()
{
std::cout
<< "The name is "
<< name
<< " and age is "
<< age
<< '\n';
}
};
int main()
{
Human cody {
.name="CODY",
.age=24,
};
cody.display();
}