Visual Studio 2010 C++ runtime error - c++

I came across strange behavior in Visual Studio 2010 C++ compiler.
Following code compiles but throws "Debug assertion failed" after execution with
message:
"_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"
Compiles and runs smoothly under GCC. Is it my fault?
#include <iostream>
#include <vector>
using namespace std;
typedef unsigned int uint;
class Foo {
vector<int*> coll;
public:
void add(int* item) {
coll.push_back(item);
}
~Foo() {
for (uint i = 0; i < coll.size(); ++i) {
delete coll[i];
coll[i] = NULL;
}
}
};
int main()
{
Foo foo;
foo.add(new int(4));
Foo bar = foo;
return 0;
}

You didn't implement a copy constructor and copy assignment operator (see rule of three). This results in a shallow copy of the pointers in your vector, causing a double delete and the assertion. EDIT: Double delete is undefined behavior so both VS and gcc are correct here, they're allowed to do whatever they want.
Typically when you implement a destructor with non-trivial behavior you'll also need to write or disable copy construction and copy assignment.
However in your case do you really need to store the items by pointer? If not, just store them by value and that would fix the problem. Otherwise if you do need pointers use shared_ptr (from your compiler or boost) instead of raw pointers to save you from needing to write your own destructor/copy methods.
EDIT: A further note about your interface: Interfaces like this that transfer ownership of passed in pointers can cause confusion by people using your class. If someone passed in the address of an int not allocated on the heap then your destructor will still fail. Better is to either accept by value if possible, or clone the passed in item making your own call to new in the add function.

You're deleting item twice, because the line
Foo bar = foo;
Invokes the default copy constructor, which duplicates the itempointer, rather than allocating and copying the data.

The problem is both the bar and foo member's vector element is same. When foo goes out of scope it's destructor is called which deallocates the pointer leaving the bar vector element dangling.bar destructor tries to deallocate it's vector element which was left dangling and is causing you the runtime error. You should write a copy constructor.
Foo bar = foo; // Invokes default copy constructor.
Edit 1: Look at this thread to know about Rule of three

The simpler solution here is not to use int* in the first place.
#include <iostream>
#include <vector>
using namespace std;
typedef unsigned int uint;
class Foo {
vector<int> coll; // remove *
public:
void add(int item) { // remove *
coll.push_back(item);
}
// remove ~Foo
};
int main()
{
Foo foo;
foo.add(4); // remove `new` call
Foo bar = foo;
return 0;
}
In general, try to avoid new.
If you cannot, use a smart manager (like std::unique_ptr) to handle the memory clean-up for you.
In any case, if you're calling delete manually, you're doing it wrong. Note: not calling delete and letting the memory leak is wrong too

Related

C++ another unique_ptr incomplete type question

Have looked at various similar questions here but still can't figure out why the following code does not compile:
// these three are defined somewhere
class A;
std::unique_ptr<A> make_a();
void take_a(std::unique_ptr<A>&&);
int main(){
take_a(make_a()); // this fails
return 0;
}
According to this:
If the default deleter is used, T must be complete at the point in
code where the deleter is invoked, which happens in the destructor,
move assignment operator, and reset member function of
std::unique_ptr.
As far as I understand, none of these (destructor, move assignment operator, nor reset member function) happens in main.
So why does compiler needs the definition of A here?
Since main has a unique_ptr within its scope, realistically it would need to know how to delete the object it holds.
It's possible that take_a doesn't actually take ownership of the object, thus main would need to delete.
main gets a temporary unique_ptr from make_a(), let's call it X. It then passes an rvalue reference to X to take_a. It still has the destroy X. Hence, it has to call the destructor after take_a, even though X would typically be empty at that point.
We need class A description (at least constructor and destructor) in order to create and move std::unique_ptr<A> objects; take_a(make_a()) is creating such object because make_a() is pass-by-value. It first creates a new unique_ptr<A> object, initialize it (using default constructor), and then update its value and returns this new object. Here the default constructor/destructor is being used, which the compiler is unable to find.
#include <bits/stdc++.h>
class A {
public: A() {}
public: ~A() {}
};
std::unique_ptr<A> make_a() {
std::cout << "make";
std::unique_ptr <A> tt = nullptr;
return tt;
}
void take_a(std::unique_ptr<A>&&) {
std::cout << "take";
}
int main(){
take_a(make_a()); // this works now
return 0;
}
Edit: Forgot to add the link. Works the other way too.

When std::vector push_back() the object which has the reference member

#include <iostream>
#include <vector>
class myClass {
public:
double a;
double& ref;
myClass() : ref(a)
{
a = 1;
}
~myClass() {}
};
using namespace std;
int main()
{
vector<myClass> myVector;
int nIter = 5;
while (nIter--) {
myVector.push_back(myClass());
}
return 0;
}
Hi.
I have myClass and I would like to push_back the myClasses and bring them together in one vector.
But unfortunately, I have to use a reference in myClass.
The problem is when the temporary object destructs, the reference becomes invalid and vector contains the object whose reference is invalidated.
After investigating, I was able to see that those reference variables are pointing at (referencing) the same memory.
I would like to find the way where each vector's element's reference member variable references each vector's element's a(member variable).
Is there any way to achieve this..?
Addition
I would like to describe my situation further.
I have one middle-sized project. In there, the users have the option to choose which variable among member variables will be used in my algorithm. so I made the script in which ref variable is used so that it can change according to the option.
I hope my explanation was clear.
You're getting this behavior because you are initializing your 'ref' member to a value that is on the stack, then the default copy constructor is copying that into the vector.
For example, in my debugger the value I have for ref is:
+ &myVector[1].ref 0x00eff80c {2.0000000000000000} double *
+ &myVector[1] 0x00126940 {a=2.0000000000000000 ref=2.0000000000000000 }
+ myVector { size=0x00000002 } std::vector<myClass,std::allocator<myClass> >
+ &nIter 0x00eff8f0 {0xffffffff} int *
You can see that myVector[1].ref is not inside myVector[1] as you'd expect, and is, in fact, on the stack. You can see that nIter and ref are only 57 bytes apart:
&nIter - (int*)&myVector[0].ref 57
If you want to see how this is implicitly happening you can delete your copy constructor:
myClass(myClass const &rhs) = delete;
inside myClass and you'll get an error at push_back.
Another option is to write your own copy constructor:
myClass(myClass const &rhs) : ref(a) {
a = rhs.a;
}
If you debug this you'll see that the values are correct, and that the memory locations of each ref are now inside the bounds of the myClass objects.
Finally you might be able to use emplace_back instead of push_back, which will construct myClass directly in the vector's memory instead of calling the copy ctor, though I wouldn't recommend this as it leaves this ref copy bug.
also don't forget the assignment operator if you go the copy ctor route:
https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
e.g.
myClass baz;
baz = myVector[0];
this will invoke operator= and not the copy ctor. My compiler (visual studio c++ latest) automatically deletes operator= if you declare a copy ctor, so it would catch this, but your compiler may not.

How to avoid deletion of object given as a parameter in C++

I am new to C++ and I do not know how to solve the following problem.
The class Foo has a constructor which creates a array of doubles of a given size. The destructor deletes this array. The print method prints the array.
#include <iostream>
class Foo {
private:
int size;
double* d;
public:
Foo(int size);
~Foo();
void print();
};
Foo::Foo(int size)
{
this->size = size;
d = new double[size];
for (int i = 0; i < size; i++)
{
d[i] = size * i;
}
}
Foo::~Foo()
{
delete[] d;
}
void Foo::print()
{
for (int i = 0; i < size; i++)
{
std::cout << d[i] << " ";
}
std::cout << std::endl;
}
Now I have a function func(Foo f) which does nothing.
void func(Foo f){}
int main()
{
Foo f(3);
f.print();
func(f);
Foo g(5);
f.print();
return 0;
}
Executing this code gives the following output:
0 3 6
0 5 10
Although I am printing f both times, somehow the values inside the array have changed.
I guess that the destructor of Foo is called on parameter Foo f after the execution of func(Foo f) and this frees the allocated memory for d, which is reallocated for Foo g(5). But how can I avoid this without using vectors or smart pointers?
The problem is with the design of the class. The default copy constructor will create a new instance of Foo when passed by value into the free standing function named func.
When the instance of Foo named f exits scope then the code invokes the user-provided destructor that deletes the array of doubles. This opens the code to the unfortunate situation of deleting the same array twice when the original instance of Foo named f exits scope at the end of the program.
When run on my machine, the code does not produce the same output. Instead I see two output lines of 0 3 6 followed by fault indicating the double free operation.
The solution is to avoid the copy by passing by reference (or by const reference): void func(Foo const &f) { } or to supply a valid copy constructor that makes a deep copy of the underlying array. Passing by reference is just a bandaid that avoids exercising the bug.
Using std::vector<double> fixes the problem because the default copy constructor will perform a deep copy and avoid double deallocation. This is absolutely the best approach in this small example, but it avoids having to understand the root of the problem. Most C++ developers will learn these techniques then promptly do what they can to avoid having to write code that manually allocates and deallocates memory.
You should probably pass the object as a reference func(Foo& f) or - if you do not want to modify it at all - as a constant reference func(const Foo& f). This will not create or delete any objects during the function call.
Aside from that, as others have already mentioned, your class should better implement the Rule of Three.
When you pass a value to a function, it is supposed to be copied. The destructor is run on the copy and should no effect on the original object. Foo fails to implement a copy constructor, so compiler provides the default one which simply performs a member-wise copy of the struct. As a result, the "copy" of Foo inside Func contains the same pointer as the original, and its destructor frees the data pointed to by both.
In order to be usable by idiomatic C++ code, Foo must implement at least a copy constructor and an assignment operator in addition to the destructor. The rule that these three come together is sometimes referred to as "the rule of three", and is mentioned in other answers.
Here is an (untested) example of what the constructors could look like:
Foo::Foo(const Foo& other) {
// copy constructor: construct Foo given another Foo
size = other->size;
d = new double[size];
std::copy(other->d, other->d + size, d);
}
Foo& Foo::operator=(const Foo& other) {
// assignment: reinitialize Foo with another Foo
if (this != &other) {
delete d;
size = other->size;
d = new double[size];
std::copy(other->d, other->d + size, d);
}
return *this;
}
Additionally, you can also modify functions like func to accept a reference to Foo or a constant reference to Foo to avoid unnecessary copying. Doing this alone would also happen fix the immediate problem you are having, but it would not help other issues, so you should definitely implement a proper copy constructor before doing anything else.
It's a good idea to get a good book on C++ where the rule of three and other C++ pitfalls are explained. Also, look into using STL containers such as std::vector as members. Since they implement the rule of three themselves, your class wouldn't need to.
One problem is that calling func creates a bitwise copy. When that copy goes out of scope the destructor is called which deletes your array.
You should change void func(Foo f){} to void func(Foo& f){}.
But better yet you add a create copy constructor or add a private declaration to stop it being called unexpectedly.

Returning a Class that Stores on Heap

I'm having a memory-related crash in my project. I managed to reduce it down to the following "toy" project:
class Foo {
public:
Foo() : bar(nullptr) {
bar = new int(3);
}
~Foo() {
if (bar) {
delete bar;
bar = nullptr;
}
}
private:
int* bar;
};
Foo test() {
Foo foo;
return foo;
}
int main() {
test();
// <--- Crash!
return 0;
}
I cannot figure out why I'm crashing at the line specified. This is what I've gathered so far, please do correct me if I'm wrong:
Basically, I'm creating foo on the stack in test(). Foo allocates some memory on the heap. All is well. Then I try to return foo. foo is returned, but it is immediately destroyed. Then, when exiting, I'm again trying to destroy foo; and hence I'm calling Foo's destructor twice, and I crash. What I do not get is why this is a problem. I'm checking for Foo::bar being null before deleting it, and if I do delete it, I set it to null afterwards.
Why should this cause a crash? How can I "fix" this? What am I doing wrong? I'm so confused! :(
Update: The main reason for why this is happening is because of lack of a copy constructor, as stated in the answers below. However, my original project did have copy constructor, or so I thought. Turns out if your class is derived, you must explicitly create a copy constructor for the derived class. Base(const Derived& other) does not count as a copy constructor!
You violated the rule of three.
When you're manually managing memory inside your constructor and destructor, you MUST also provide a copy constructor and assignment operator, otherwise your program will double-delete and use memory after delete.
In your particular example, you have the compiler-provided copy constructor. When foo is copied to the return value of test, you have two objects with the same bar pointer. The local foo goes out of scope and is destroyed, then its bar is set to nullptr. But the copy, the return value, still has a non-null pointer. Then it is destroyed also, and deletes the same memory again.
You need to implement a copy-constructor and, most likely, an assignment operator.
Really, though, your problem lies in manually managing memory. This is almost always a terrible idea, as it is one of the most common ways bugs creep into your code. Use shared_ptrs instead of manually managing memory in your code, and it is amazing how much easier your code is to maintain!

Malloc on a struct containing a std::vector

Here is the situation :
I use a malloc to allocate memory for a struct.
The struct contains various items such as pointers, string variables and vectors.
The fact is, when we use malloc, no constructors are called. Using a code similar to the following one, I've experienced some situation where some variables worked while others didn't.
Note : The following code doesn't compile. It's purpose is only to illustrate the situation.
struct MyStruct
{
MyClass* mFirstClass;
bool mBool;
std::string mString;
std::vector<MyClass> mVector;
};
int main()
{
MyStruct* wMyStructure;
wMyStructure = (MyStruct*) malloc (sizeof(MyStruct));
MyClass wMyClassObject;
wMyStructure->mFirstClass = new MyClass();
wMyStructure->mFirstClass->func();
wMyStructure->mBool = false;
wMyStructure->mString = "aString";
wMyStructure->mVector.push_back(wMyClassObject);
return 0;
}
By using pointers instead of those variables (std::string* mString), followed by a call to the object constructor (mString = new std::string;) Exception are not thrown.
However, I've experienced a situation where the mString was used without problem without the constructor being called, but when it came to the vector, the application exit automatically.
This left me with many questions:
When will an object throw an exception if no constructor were used?
In the situation I experienced, only the vector caused problem. Could mString be left as it is or should I call it's constructor?
What would be the safest way, using malloc, to do the whole thing?
Using object without constructing it must be an undefined behaviour. Anything may happen at any moment. If you do this, you must not rely on any part of your code to run smoothly, because the language doesn't guarantee anything in this case.
Your code causes undefined behaviour, because your wMyStructure does not point to an object, so you may not use the accessor operator -> on it.
An object only commences its life after its constructor has completed. Since you don't call any constructor, you do not have an object.
(If your struct were a POD, i.e. just consisting of primitive types and PODs, then this would be OK, because PODs have trivial constructors, which do nothing.)
The concrete problem you're facing is that the string and vector members of your struct didn't get to call their constructors, so those members don't exists, and hence the entire object doesn't.
If you want to decouple memory management from object construction, you can use placement syntax:
// get some memory
char arena[HUGE_VAL];
void * morespace = malloc(HUGE_VAL);
// construct some objects
MyClass * px = new (arena + 2000) MyClass; // default constructor
YourClass * py = new (morespace + 5000) YourClass(1, -.5, 'x'); // non-default constructor
(You have to destroy those objects manually, px->~MyClass(); etc., when you're done with them.)
It is undefined behaviour to use a non-initialized object. Exception may be thrown at any time- or not at all.
1 ) When will an object throw an exception if no constructor were used ?
If you don't call the constructor, there is no object. You have just allocated some space.
2 ) In the situation I experienced, only the vector caused problem. Could mString be left as it is or should I call it's constructor ?
This is all undefined behavior, just about anything could happen. There are no rules.
3 ) What would be the safest way, using malloc, to do the whole thing ?
The safest way would be not to use malloc, but allocate using new that will call constructors. It is as simple as this
MyStruct* wMyStructure = new MyStruct;
None of the other answers appear to explain what the compiler is doing. I'll try to explain.
When you call malloc the program reserve some memory space for the struct. That space is filled with memory garbage, (i.e. random numbers in place of the struct fields).
Now consider this code:
// (tested on g++ 5.1.0 on linux)
#include <iostream>
#include <stdlib.h>
struct S {
int a;
};
int main() {
S* s = (S*)malloc(sizeof(S));
s->a = 10;
*((int*)s) = 20;
std::cout << s->a << std::endl; // 20
}
So when accessing a member of a struct you are actually accessing a memory position, there should be no unexpected behavior when writing to it.
But in C++ you can overload operators. Now imagine what would happen if the overloaded assignment operator need the class to be initialized, like in the code below:
// (tested on g++ 5.1.0 on linux)
#include <iostream>
#include <stdlib.h>
class C {
public:
int answer;
int n;
C(int n) { this->n = n; this->answer = 42; }
C& operator=(const C& rhs) {
if(answer != 42) throw "ERROR";
this->n = rhs.n; return *this;
}
};
struct S {
int a;
C c;
};
int main() {
S* s = (S*)malloc(sizeof(S));
C c(10);
C c2(20);
c = c2; // OK
std::cout << c.n << std::endl; // 20
s->c = c; // Not OK
// Throw "ERROR"
std::cout << s->c.n << std::endl; // 20
}
When s->c = c is executed the assignment operator verifies if s->c.answer is 42, if its not it will throw an error.
So you can only do as you did in your example if you know that the overloaded assignment operator of the class std::vector does not expect an initialized vector. I have never read the source code of this class, but I bet it expects.
So its not advisable to do this, but its not impossible to be done with safety if you really need. You just need to be sure you know the behavior of all assignment operators you are using.
In your example, if you really need an std::vector on the struct you can use a vector pointer:
class MyClass { ... };
struct S {
std::vector<MyClass>* vec;
}
int main() {
S s;
MyClass c;
s.vec = new std::vector<MyClass>();
s.vec->push_back(c);
}