What i think is occuring is that the rvalue A returned by SetVar is an identical copy to Class and shares the same pointer Var. but when the rvalue calls its deconstructor it deletes Class's Val.
class A
{
private:
int* Var;
public:
A SetVar(int);
~A()
{
delete Var;
}
};
A A::SetVar(int NewVar)
{
Var=new int;
*Var=NewVar;
//POINT A
return *this;
}
int main()
{
A Class;
Class.SetVar(8);
//POINT B
}
At POINT A *Val equals 8, but at POINT B *Val equals -17891602. I also Get _BLOCK_TYPE_IS_VALID(pHead->nHeadUse) due to trying to delete Val twice.
deleting the deconstructor solves the issue but creates a memory leak.
You have violated The Rule of Three
So, you make a copy of the object when you do
return *this
which gets destructed as well, and delete is called twice on the same pointer. You really shouldn't be doing this anyway. You should return a reference, but why should a setter function return a reference to the object it was called on anyway? Isd it to chain function calls?
Additionally, you are leaking Var every time you reassign it.
There are a few problems here.
First, the most direct cause of you problem is that a copy of the this object is made when SetVar() returns. (You probably want to return a reference to an A instead.) Since there is no copy constructor defined for class A, the values of all of the fields are implicitly copied. This means that the copy will have a pointer to the same Var int that you allocated in SetVar. In other words, you will have two pointers to the same memory, one in the original A variable (the one you call "Class") and one in the copy that is returned by SetVar(). When the second of these is destroyed, its destructor will be deleting the memory at an already-deleted pointer.
Related
I write a simple class, I just wanna know where I should delete my pointer.
#include<iostream>
class test
{
private:
int* sum{new int};
public:
int addFunc(int num1 = 5, int num2 = 2)
{
*sum = num1 + num2;
return *sum;
}
void print()
{
std::cout << *sum << std::endl;
}
};
int main()
{
test obj;
obj.addFunc();
obj.print();
}
I know how to use unique pointers to get rid of deleting pointers, should I delete my pointer after
returning it or somewhere else.
You delete it in the destructor. But if you're managing raw memory you'll also have to implement a suitable copy constructor & copy assignment operator and their move counterparts.
In 99%+ of these cases you'll just want to use automatic lifetime or smart pointers instead.
Short answer: never, meaning at program end.
The problem is that your class is copyable. If you delete the pointer in destructor (which would be the correct place for something allocated at construction time), you will get a dangling pointer in the following use case:
you pass a reference to a test object to a function
inside that function you copy the object to a local object: the pointer will be copied so both the original object and the local copy will point the the same int
at the end the the function, the local object will be destroyed. If if deletes the int, the original will get a dangling pointer.
Long story made short: as soon as you use allocation at construction time, you should care for the copy/move construction and assignment, and destruction.
Can anyone explain the meaning of *p=*q in this C++ code? Is this a copy constructor concept?
class A{
//any code
}
int main(){
A *p=new A();
A *q=new A();
*p=*q;
return 0;
}
Is this a copy constructor concept?
No, what you are referring to is a copy assignment concept. Consider this:
int* p = new int{9};
int* q = new int{10};
*p = *q;
As you can see above, only the value of the variable q which is pointed to is copied. This is the equivalent of the copy assignment for objects. If you were to do this:
p = q;
Then this would not be a copy assignment, because both int's point to the same address and value, meaning any change to p or q would be reflected on the other variable.
To give a more concrete and validated example, here is some code:
int main()
{
int* p = new int{9};
int* q = new int{10};
*p = *q;
//p = 10, q = 10
*p = 11;
//p = 11, q = 10
delete p;
delete q;
}
And here is a supplementary counter-example
int main()
{
int* p = new int{9};
int* q = new int{10};
p = q;
//p = 10, q = 10
*p = 11;
//p = 11, q = 11
delete p;
//delete q; Not needed because p and q point to same int
}
As you can see, the changes are reflected on both variables for p=q
Side Note
You mentioned copy-construction, but you were unclear about the concept. Here is what copy-construction would have looked like:
int* p = new int{9};
int* q = new int{*p}; //q=9
Copy construction differs from copy assignment in the sense that with copy construction, the variable doesn't already have a value, and for an object, the constructor has yet to be called. Mixing up the 2 terms is common, but the fundamental differences make the two concepts, well, different.
It looks like, you're unclear about the copy constructor and copy assignment. Let's first have a look at both concepts individually, and then I'll come to your question. The answer is a little long, so be patient :)
Copy Constructor
Here, I'm not going to explain how to write a copy constructor, but when the copy constructor is called and when it's not. (If you want to know, how to write a copy constructor, see this)
A copy constructor is a special constructor for creating a new object as a copy of an existing object. (It is called whenever there's a need for making a copy of an existing object)
These are the scenarios when the copy constructor will be called to make the copy of an existing object:
Initializing an object with some previously created object:
SomeClass obj;
// ...
SomeClass anotherObj = obj; // here copy constructor will be called.
See, SomeClass obj; statement is simply creating an object (here, default constructor will be called to create the object). The second statement SomeClass anotherObj = obj; is instantiating an object, initialized with the values of obj (an existing object), so copy constructor will be called here. You can also initialize an object with an existing object this way: SomeClass anotherObj(obj); (This statement is equivalent to SomeClass anotherObj = obj;)
Except:
If you initialize with some rvalue expression. e.g.
SomeClass someObject = aObject + anotherObject;
In this case, move constructor will be called. See, What are move semantics?
Passing an object by value to some function (see Passing arguments by value):
See, the following code snippet, here the function doSomething is accepting an object as parameter by value:
void doSomething(SomeClass someObject)
{
// ...
}
There are some cases, when there will be a need to make the copy of the passed argument in the parameter object someObject, I've listed when there will be a need to make the copy and when there'll not be a need.
Have a look at the following code snippet:
SomeClass someObject;
// ...
doSomething(someObject); // here copy constructor will be called.
The statement SomeClass someObject; is just instantiating someObject by calling the default constructor.
The second statement doSomething(someObject); is calling the function doSomething previously shown, by passing someObject as argument. This is the case, when there's a need to make a copy of someObject to pass to the function.
Except:
Similiary, If we call doSomething with some rvalue expression, it will call move constructor instead of copy constructor.
Returning an object from a function by value:
Let's have a look at the following definition of doSomething
SomeClass doSomehing()
{
SomeClass someObject;
// ...
return someObject;
}
In the above function doSomething, an object of SomeClass is being created and after doing some task, the object is being returned by the function, in this case, a copy of the someObject will be created and returned.
Except:
Similiary, If doSomething returns some rvalue expression, it will call move constructor instead of copy constructor.
Copy Assignment
Copy Assignment is usually confused with the copy construction, let's have a look at how it is different than the copy construction:
SomeClass someObject;
// ...
SomeClass anotherObject;
// ...
anotherObject = someObject; // here copy assignment operator will be called.
The first two statements are just creating someObject and anotherObject, you see, the third statement is actually calling the copy assignment operator and not the copy constructor.
Constructors are only called when some new object is being created. And in the case of anotherObject = someObject;, both the objects are already created, so there won't be any call to the copy constructor. Instead a copy assignment operator will be called (to see, how to overload a copy assignment operator, see this)
Now, let's have a look at your code snippet:
A *p=new A();
A *q=new A();
*p=*q;
In the first statement A *p=new A();, default constructor will be called to create an object (in this case, new object will be created on heap) and p will be initialized with the address of the newly created object (as p is a pointer)
Similar is the case with second statement A *q=new A(); (It is creating another object and q will be initialized with newly created object)
Now, the third statement: *p = *q; (here * is Dereference operator)
To understand, what the third statement is doing, let's have a look at some pointers and de-referencing them to get the actual object, which they're pointing to.
int someVariable = 5;
int *somePointer = &someVariable;
// ...
*somePointer = 7;
Let's try to understand the above code snippet: someVariable is created and initialized with a value of 5, then somePointer is created and initialized with the address of someVariable.
Now, the last statement *somePointer = 7;, it is actually de-referencing the somePointer and by de-referencing, it'll get the the variable which it is pointing to. (so it will get someVariable) and then it is assigning 7 to it. So after this statement, someVariable's value will become 7
Let's have another example:
int* somePointer = new int;
int* anotherPointer = new int;
// ...
*somePointer = 5;
*anotherPointer = 7;
// ...
*somePointer = *anotherPointer;
First, somePointer will be created and initialized with the address of dynamically allocated int variable (will be allocated in heap, see Dynamic Allocation in c++), similarly, anotherPointer will be initialized with the address of another dynamically allocated variable.
Then, it is assigning 5 to the first variable (which is being pointed by somePointer) and 7 to the second variable (which is being pointed by anotherPointer)
Now, the last statement will be of your interest, *somePointer = *anotherPointer;, in this statement *somePointer is de-referencing and getting the first variable (whose value was 5) and *anotherPointer is de-referencing and getting the second variable (whose value is 7), and it is assigning the second variable to the first variable, resulting in changing the first variable's value to 7.
Now, let's have a look at your *p=*q; statement, (p was pointing to the first object of A, and q was pointing to the second object of A, both dynamically allocated), *p will dereference p and get the first object, *q will dereference q and get the second object, and then the second object will be copied in the first object, and if you see, no new object is being created in *p=*q;, and only the value of second object is being created in the first object, so copy assignment operator will be called here and no the copy constructor.
Another thing
You should de-allocate the dynamically allocated memory which you borrowed using new operator:
delete p;
delete q;
You should add these two lines at the end of your program, so to avoid Memory Leak.
As stated in the comments, one need to understand the basics first:
With A *p=new A(); one gets a pointer to a memory region on the heap in which an object of type A is constructed.
With *p one dereferences the pointer, i.e. one retrieves the object.
Now *p = *q uses the (possibly implicitly declared) assignment operator of class A in order to give *p -- the object pointed to by p -- the value of *q. This operation could equivalently be written as p->operator=(*q).
The last step, the assignment, is identical to what you would obtain with objects instead of pointers (which is usually a better way to go in C++ and often called RAII):
A r;
A s;
r=s;
I am learning pointers in c++ and am having some trouble.
I have a class Foo that in the header file declares some data:
private:
const Bar *obj;
Where Bar is a class.
Then in the c++ implementation I want to replace *obj so that it points to a completely different Bar object. *obj is constant, so how do I change what is in what *obj points to or rather, what is in memory at *obj? Also in Foo's destructor, how do I deallocate *obj?
Given your class definition
class A {
private:
const Bar *obj;
};
obj is a pointer to a constant Bar object. You can change what that pointer points to, but you cannot change the contents of the object pointed to.
So, if you have a new Bar object and you'd like to change obj so it points to that, you can simply assign the new value:
/* New object: */
Bar *new_bar = new Bar;
/* Change the pointer: */
obj = new_bar;
There are two issues, however.
If the new Bar object is created outside the class, you cannot directly assign it to obj because the latter is private. Hence you need a setter function:
class A {
private:
const Bar *obj;
public:
void set_obj(const Bar *new_obj) { obj = new_obj; }
};
You must determine who will eventually own the Bar object, i.e. who is responsible for freeing the heap space it takes. If the caller is responsible then you can code it as above, i.e. class A will never create new Bar objects, nor delete any. It will just maintain a pointer to Bar objects created and deleted outside the class.
But if class A above is actually responsible for the memory space taken by the Bar objects, you must use delete obj in the destructor to free the space, and you must also free the space when you get a new Bar object assigned. That is, the set_obj function above needs to be changed to this:
void set_obj(const Bar *new_obj) { delete obj; obj = new_obj; }
Otherwise you'll have a memory leak. Similar measures must be taken in the copy constructor (unless you delete it), as well as the assignment operator: Both functions are used whenever a copy of a class A object is made, and in that case you must make sure that you do not simply copy the pointer, but instead allocate fresh space and copy the object (i.e. you must perform a deep copy):
A(const A& a):obj(new Bar(*a.obj)) {}
A& operator=(const A& a) { delete obj; obj = new Bar(*a.obj); return *this; }
Having said this, if your class is responsible for the memory space, it is a much better idea to use a smart pointer class instead of a raw pointer. The main reasons are: (i) The above is quite complicated and it's easy to make mistakes; (ii) The above is still not very good – there may still be memory leaks or worse problems when an exception is thrown, e.g. in the constructor of Bar. C++11 provides a smart pointer class called std::unique_ptr, which seems ideal for your purposes:
class A {
private:
std::unique_ptr<const Bar> obj;
public:
~A() {}
void set_obj(std::unique_ptr<const Bar> new_obj) { obj = new_obj; }
};
With this in place, the smart pointer will take care of any memory space that needs to be freed automatically, both at destruction time as well as when a new Bar object is assigned to the pointer.
You cannot use that pointer to to change the value that's being pointed to, that's why it's a const, but you should be able to change what it is pointing to.
On c++ "const Bar *obj;" means that you have a pointer to a readonly Bar object; meaning that you can point it to any readonly Bar object.
You can also point a non constant variable, thus promising that you will not change it using that pointer.
If you want to have a pointer, that is constant in the sense that it can't be made to point anything else, then you should write it this way:
Bar * const obj = some_object;
This will compile and work fine:
const int p = 1, q = 2;
int r = 3;
const int* i = &p;
i = &q; // point it to a different const variable.
i = &r; // point it to a different non const variable.
As written I believe that this is a pointer to a const Bar object and not a constant pointer.
here is my c++ code :
class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}
~Sample()
{
delete ptr;
}
void PrintVal()
{
cout << "The value is " << *ptr;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
}
it returns me the output like :
Say i am in someFunc
Null pointer assignment(Run-time error)
here As the object is passed by value to SomeFunc the destructor of the object is called when the control returns from the function
should i right ? if yes then why it is happening ? and whats the solution for this ???
Sample is passed by value to SomeFunc, which means a copy is made. The copy has the same ptr, so when that copy is destroyed when SomeFunc returns, ptr is deleted for both objects. Then when you call PrintVal() in main you dereference this invalid pointer. This is undefined behavior. Even if that works then when s1 is destroyed ptr is deleted again, which is also UB.
Also, if the compiler fails to elide the copy in Sample s1= 10; then s1 won't even be valid to begin with, because when the temporary is destroyed the pointer will be deleted. Most compilers do avoid this copy though.
You need to either implement copying correctly or disallow copying. The default copy-ctor is not correct for this type. I would recommend either making this type a value type (which holds its members directly rather than by pointer) so that the default copy-ctor works, or use a smart pointer to hold the reference so that it can manage the by-reference resources for you and the default copy-ctor will still work.
One of the things I really like about C++ is that it's really friendly toward using value types everywhere, and if you need a reference type you can just wrap any value type up in a smart pointer. I think this is much nicer than other languages that have primitive types with value semantics but then user defined types have reference semantics by default.
You usually need to obey the Rule of Three since you have an pointer member.
In your code example to avoid the Undefined Behavior you are seeing:
Replace the need to in first statement by must.
Since SomeFunc() takes its argument by value, the Sample object that you pass to it is copied. When SomeFunc() returns, the temporary copy is destroyed.
Since Sample has no copy constructor defined, its compiler-generated copy constructor simply copies the pointer value, so both Sample instances point to the same int. When one Sample (the temporary copy) is destroyed, that int is deleted, and then when the second Sample (the original) is destroyed, it tries to delete the same int again. That's why your program crashes.
You can change SomeFunc() to take a reference instead, avoiding the temporary copy:
void someFunc(Sample const &x)
and/or you can define a copy constructor for Sample which allocates a new int rather than just copying the pointer to the existing one.
When you pass the argument for the function it's called the copy constructor, but you don't have one so the pointer is not initialised. When it exits the function, the object is calls the destructor to delete the unitialised pointer, so it thows an error.
Instead of
int main()
{
Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
}
try to use
int main()
{
Sample* s1= new Sample(10);
SomeFunc(*s1);
s1->PrintVal();
}
I have the following class:
class FixedByteStream {
public:
FixedByteStream() : size(0), address(NULL), existing(false) {}
FixedByteStream(int length) : existing(false) {
size = length;
address = new char[length];
}
FixedByteStream(int length, char* addr) : existing(true) {
size = length;
address = addr;
}
FixedByteStream(string* str, bool includeNull = false) : existing(true) {
size = (*str).length();
address = const_cast<char*>((*str).c_str());
if (includeNull){
++size;
}
}
~FixedByteStream() {
if (existing == false) {
delete [] address;
}
address = NULL;
}
int getLength() {
return size;
}
char* getAddressAt(int index) {
return &(address[index]);
}
char& operator[] (const int index) {
return address[index];
}
operator char*() {
return address;
}
private:
bool existing;
int size;
char* address;
};
And a very simple test that is able to produce the issue:
FixedByteStream received;
received = FixedByteStream(12);
received[0] = 't';
Valgrind warns about an invalid write, and debugging has shown why. FixedByteStream received; calls the constructor with no arguments (which is kind of stupid because it can't do anything). received = FixedByteStream(12); calls the constructor with the integer argument... and then immediately calls the destructor on itself, invalidating the object. It still works for some reason, but I'd rather it not be placed in such an odd predicament that throws warnings.
So, why is it being called there? I could somewhat understand if the destructor were called first, to get rid of the useless temporary object (not that it needs to), but I have used that kind of declare-now-assign-later pattern practically everywhere and never had such an issue before.
You are missing an assignment operator. Remember the rule of three (or five).
The problem is roughly like this:
T t; // default constructed t
t = T(2); // T(2) constructor with a single argument, assignment operator= called with this == &t
You provide no assignment operator so the pointer value in the temporary is simply copied into t and then the memory pointed to is deleted in the destructor of the temporary.
Also: Don't have a default constructor, if the object constructed is invalid.
If you object has any user defined constructor it is always constructed using a constructor. Just defining an object without any constructor arguments uses the default constructor independent of whether the object is being overwritten afterwards. That is
FixedByteStream received;
will call the default constructor. The next line is a bit more interesting:
received = FixedByteStream(12);
This line create a temporary FixedByteStream with the argument 12. Internally this will allocate some memory but since temporaries are destroyed at the end of the full expression (in this case essentially when the semicolon is reached) that won't you do much good. Once this temporary object is constructed it is assigned to received using the automatically generated copy assignment which would look something like this if you'd write it manually:
FixedByteStream& FixedByteStream::operator= (FixedByteStream& other) {
this->existing = other.existing;
this->size = other.size;
this->address = other.address;
return *this;
}
That is, once this assignment is executed, you have to identical copies of FixedByteStream, one of which is about to be destroyed and will release the resources just allocated. This is clearly not what you want, i.e. you definitely need to implement the copy assignment operator to make your class well-behaved. In general, the presence of a destructor which does anything interesting is a good hint at the fact that you'll need an assignment operator as well. In fact, there is another one of the generated operations, namely the copy constructor, which does roughly what the copy assignment does except that it copy constructs the members instead of assigning them. This is also not what you want with your class.
Now the interesting question becomes: how can FixedByteStream be fixed? Effectively, you'll need either to use reference counting to keep track of how many objects are currently looking at the FixedByteStream, allocate a copy of the content, or you need to use move semantic support (aka rvalue references) which is only available in C++2011. Unless you really know what you are doing I'd recommend copying the stream in all cases and leave a more advanced approach for later.
Step by step:
//create a new object using the default constructor
//I don't see why you think it's stupid that the constructor is called
//it's doing what you're telling it to do
FixedByteStream received;
//FixedByteStream(12) creates a temporary object
//you then copy this object in the received object you already have
//you're using the default operator =
//the temporary object is deleted after it is copied to received
received = FixedByteStream(12);
//received is a valid object
received[0] = 't';
EDIT:
As I see there's a lot of wrong answers for this question, I'll explain further. I might get some hate for this, but this is a pretty important concept and I downvoted so that a wrong answer doesn't get accepted and taken from granted.
You're basically initializing some object on the stack.
I'll simplify your case:
class A
{
A() {}
A(const A& other) {}
A& operator = (const A& other) {}
};
Let's talk about scope:
{ //begin scope
A a; //object a is created here
//default constructor is called
} //a is destroyed here
//destructor is called
So far so good.
Now, assignment:
{
//two objects are created with default constructor
A a;
A b;
//object b is assigned to a
//operator = will be called
//both objects are still alive here
a = b;
//...
} // a and b will be destroyed, destructor called
On to the last part:
{
A a;
a = A();
}
is pretty much equivalent to:
{
A a;
{
A b;
a = b;
}
}
When you call a = A(), A() creates a temporary object which is assigned to a and then destroyed.
So object b in my simplification is the temporary object that gets destroyed. Not a, your original, therefore a is still valid.
Not the assignment operator declaration. If you don't define one, a default is used. You probably want to write your own in this case.
FixedByteStream(12) is assigned to received through the default operator=. Notice that you didn't allocate FixedByteStream(12) in the heap by using new, but rather allocated it in local scope without specifying a name for the variable that would hold it.
Your code is somewhat similar to:
FixedByteStream received;
FixedByteStream temp(12);
received = temp;
received[0] = 't';
Only in my example temp has a name and its scope is the entire function, and in your test code temp doesn't have a name, it exists for one line only and then gets destroyed.
The FixedByteStream(12) object you've created cannot be used after this line because it's not even a named varaible.
Object is already initialized on this line
FixedByteStream received;
On line
received = FixedByteStream(12);
You reinitialize it. The correct way to do this is:
FixedByteStream received(12);
// Or
FixedByteStream *received;
received = new FixedByteStream(12);
(I'd definitely go for first one)
It seems you don't understand object lifecycle and mistakenly interpret this code as a Java code.
When you write FixedByteStream received; an object of type FixedByteStream is created using the no-argument constructor. And when you write received = FixedByteStream(12); another object is created, = operator is called and the newly created object is desctructed.
Also you didn't override operator= so the object is copied by bytes, which is not correct.