Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am working with the same code from this code from my previous SO post but I have made several changes. My problem is that I have a dynamic array that I call delete[] on inside of my operator overload for the copy constructor and I get the error below.
Exception thrown at 0x0F7063BB (ucrtbased.dll) in Lab3.exe: 0xC0000005: Access violation reading location 0xCCCCCCBC.
If there is a handler for this exception, the program may be safely continued.
Can anyone help me understand why?
I checked the related questions but there are different errors than from what I'm seeing and I haven't found a result in my google search. I am using C++ 11 on visual studio 2015.
#include "ListArray.h"
template < typename DataType >
List<DataType>::List ( int maxNumber )
{
//maxSize = MAX_LIST_SIZE; maybe???
maxSize = maxNumber;
dataItems = new DataType[maxSize];
size = maxSize - 1;
cursor = 0; // sets cursor to the first value in list
for (; cursor <= size; cursor++)
dataItems[cursor] = 1;
cursor = 0;
}
template < typename DataType >
List<DataType>::List ( const List& source )
{
*this = source; // should be handled by copy constructor
}
template < typename DataType >
List<DataType>& List<DataType>::operator= ( const List& source )
{
if (this != &source)
{
maxSize = source.maxSize;
size = source.size;
cursor = source.cursor;
delete []dataItems; // clears dataItems, weird run-time error here. Why?
dataItems = new DataType[size];
for (int count = 0; count < size; count++)
dataItems[count] = source.dataItems[count];
}
else
// do nothing, they are the same so no copy is made
return *this;
}
template < typename DataType >
List<DataType>::~List ()
{
maxSize = 0;
size = 0;
cursor = -1;
delete[] dataItems;
}
Edit: I initially posted several other incomplete functions also a part of the program I am trying to build. I meant only to include the ones that I know are generating my problem. My apologies for the bad post.
If you're going to use the assignment operator to make your copies, you need an empty object to start with, otherwise operator= will fail horribly when it tries to clean up the old contents before replacing them (as Sam explained in his answer and MikeCAT mentioned in his comment -- give them upvotes -- and what Dieter told you on your earlier question).
Since C++11, constructor chaining aka constructor delegation is possible, like this:
template < typename DataType >
List<DataType>::List ( const List& source )
: List() /* default construct object before proceeding */
{
*this = source; // should be handled by copy constructor
}
another option is to make the copy constructor responsible for creating a default object itself, and this is what would be needed in C++98 and C++03:
template < typename DataType >
List<DataType>::List ( const List& source )
: maxSize(0), dataItems(NULL), size(0) // initialize members
{
*this = source; // should be handled by copy constructor
}
But this is duplicating the function of the default constructor, so as long as your compiler has support for the C++11 feature, prefer to call the existing one.
The details of constructor delegation... get complicated. Among other things, normally any exception thrown from inside an object constructor prevents the object from ever existing, and the destructor is not called. When delegation is used, then the object becomes live when any constructor completes, and an exception inside a wrapper constructor will face an object that's already alive and call the destructor for you. This behavior may or may not be desirable, but it's something to watch out for because exception-safety is important in modern C++.
The copy constructor does not initialize anything in the new instance of the class. All it does is call the assignment operator.
The assignment operator executes:
delete []dataItems;
Since dataItems has not been initialized, this results in undefined behavior, and an immediate crash.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am programming a Space Invaders clone and I am struggling at creating the bullets.
Whenever I click Space a bullet is supposed to be added to the vector and then I want to move them via a loop, but I dont understand how to create and handle it the proper way.
vector<Bullet> bullets(MAXBULLETS);
int bulletcounter = 0;
while (1) {
Sleep(10);
for (int i = 0; i < sizeof(bullets)-1; i++) {
bullets[i].Move(0, 1);
}
if (GetAsyncKeyState(VK_SPACE)) {
Bullet *bullet = new Bullet();
bullets[bulletcounter] = bullet; // Here is the error
bulletcounter++;
}
bullets is a vector that holds objects of type Bullet.
Bullet *bullet = new Bullet();
bullets[bulletcounter] = bullet; // Here is the error
Your bullet here is of type Bullet*. The two incompatible types get you the error.
To fix this, stop using a pointer and just instantiate an object:
Bullet bullet;
This creates a Bullet object using the parameterless constructor that you can then add to your bullets.
Do note though, that this currently does nothing since you initialize your vector giving it a predefined size bullets(MAXBULLETS), this already creates MAXBULLETS default constructed objects for you, ready to use:
Constructs the container with count default-inserted instances of T.
No copies are made.
Side note : stop using new altogether; this isn't Java or C#. If you need a dynamically allocated object then use a smart pointer. Most of the time, though, an object automatic-storage duration will do just fine.
My proposal
vector<Bullet> bullets;
while (1)
{
Sleep(10);
for (int i = 0; i < bullets.size(); i++)
{
bullets[i].Move(0, 1);
}
if (GetAsyncKeyState(VK_SPACE))
{
bullets.push_back(Bullet());
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I'm currently working on a game using OpenGL ES 2.0 on Android (in C++ using the NDK).
I have a class called "Drawable" which is my base class for drawing objects using OpenGL.
In the destructor of the class I have to clean up some buffers :
Drawable::~Drawable() {
LOGE("release");
releaseBuffers();
}
But the destructor is called endlessly (as in every loop of the thread), which messes up my drawing.
I'm kind of lost here and I could not find similar problems, so help is welcome!
Edit: Loop code is here : link
Edit2: I found one of the evil calls:
In my player class I have this call:
currentWeapon->draw(this);
to
void Weapon::draw(Player* p)
If I comment this, the spam is gone.
There are very few ways a destructor gets called:
1) You create an instance of Drawable on the stack, and it falls out of scope. If this is done in a tight loop, the object will fall out of scope and be destroyed at each iteration of the loop. For example:
for (size_t i = 0; i < 100; ++i)
{
Drawable d;
}
Here, 100 instances of Drawable will be created and destroyed, at the beginning and end of every loop.
2) You delete a dynamically-allocated Drawable:
for (size_t i = 0; i < 100; ++i)
{
Drawable* d = new Drawable;
delete drawable;
}
3) You call the destructor explicitly:
Drawable* b = new (buffer) Drawable;
b->~Drawable()
Note that #3 uses "placement new" and is highly unlikely.
Objects can be destroyed at suprising times when they are in a container such as a vector. Consider:
vector <Drawable> drawables;
for (size_t i = 0; i < 10000; ++i)
{
Drawable d;
drawables.push_back (d);
}
You will notice potentially many destructor calls when you run this code. When you push_back, a copy is potentially made and the original (d here) is destroyed. Also, when the vector reaches capacity it has to reallocate, which results in every item being copied again, and the originals destroyed.
Objects can also be destroyed at suprising time in the face of temporaries and unexpected copies. Consider:
void DoSomething (Drawable d)
{
}
int main()
{
Drawable d;
for (size_t i = 0; i < 1000; ++i)
{
DoSomething (d);
}
}
This is a naive example because the compiler will likely elide the temporaries in this case. But since DoSomething() takes a Drawable by-value a copy of the original could be made. Depending on other code, the compiler might not even be able to elide this copy.
This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 8 years ago.
I have problem with the following class. I think the problem is with string array, cause I made two other classes and the problem was the same. When I run the program it throws "double free or corruption", but I do not think any double corruption is possible. The problem is same with input string as reference or as common argument in Add method.
class WareH
{
public:
WareH(void)
{
first = true;
rows = 1;
inLine = 0;
cnt = 0;
max = 2;
cL = 0;
strs = new string[max];
}
~WareH(void)
{
delete [] strs;
}
bool Add(string& str, int ending)
{
if (first)
inLine++;
else
cL++;
if (ending == 0)
{
if (first)
first = false;
if (cL != inLine)
return false;
rows++;
}
strs[cnt++] = str;
Bigger();
return true;
}
void Bigger(void)
{
if(max == cnt)
{
max *= 2;
string* tmp = new string[max];
for (int i = 0; i < cnt; i++)
tmp[i] = strs[i];
delete [] strs;
strs = tmp;
}
}
friend ofstream& operator<<(ofstream& of,WareH war)
{
for (int a = 0; a < war.cnt; a++)
of << war.strs[a] << endl;
return of;
}
private:
bool first;
int rows, inLine, cnt, max, cL;
string* strs;
};
When a class manages resources, and releases them in its destructor, you must consider the Rule of Three to make sure that copying an object will not result in two objects managing the same resource.
That is what is happening here: the default copy constructor and copy-assignment operator will copy the pointer, giving you two objects which will both try to delete the same array on destruction. Solutions are:
Delete the copy constructor and copy-assignment operator to prevent copying; or
Implement them to copy the strings into a new array, not just the pointer; or
Use std::vector rather than messing around managing memory allocation yourself.
When I run the program it throws "double free or corruption", but I do not think any double corruption is possible.
Educated guess here:
The problem is not in the code you've shown, but in the client code. Here's what I think happens:
you wrote client code that instantiates (or assigns or returns by value or stores in a std container) WareH instances, and since you do not define a copy constructor and assignment operator (see "The Big Three"), they end up copying the values from your source objects. When the first of these instances (that are assigned to each other) are deleted, they delete the strs pointer.
When the second instance is deleted, they delete the same strs pointers that were deleted before (because the default copy constructors and assignment operators do not duplicate the allocated memory but just copy the pointers).
Solutions (if that is indeed, the problem):
working (and bad) solution: explicitly define copy construction and assignment operator for your class.
working (and good) solution: implement your strs as a std::vector<std::string> instead of std::string* and cnt.
So I have the following class method (will probably add more if requested):
EDIT 1:
Here is where paObject gets initialized and how it remains until it reaches setCapacity(int c)
template <Object>
ArrayClass<Object>::ArrayClass()
{
_size = 0; //default in case allocation fails
paObject = new Object[ARRAY_CLASS_DEFAULT_SIZE];
if (paObject == NULL)
throw Exception();
_size = ARRAY_CLASS_DEFAULT_SIZE;
}
It may be important to note that my class Vector extends (or whatever it is in c++) ArrayClass: class MyVector: virtual public ArrayClass<Object>{} and then later on in
template <class Object>
MyVector<Object>::MyVector() : ArrayClass<Object>()
{
_currSize = 0;
_incFactor = 5;
}
it forces to call the ArrayClass constructor.
template <Object >
void MyVector<Object>::setCapacity(int c)
{
int len = _currSize;
if (len > c) len = c;
Object* paNew = new Object[c];
if (paNew == NULL) throw Exception();
for (int i = 0; i < len; i++)
paNew[i] = paObject[i];
if (paObject != NULL)
delete[] paObject;
paObject = paNew;
_size = c;
if (_currSize > len)
_currSize = len;
}
When the error happens, the value of c is 6 and the value of _currSize (a class private int variable) is 1. It is also remarkable to remark that paObject is a class pointer of type Object (which is a template... etc. etc.) initialized with an array of Objects of size 1 by the time the error happens (Object* paObject = new Object[1]).
Everything executes fine up until it reaches the line delete[] paObject; at which point it gives me a Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) error.
I seriously don't understand what is wrong.
Help would be appreciated.
This error occurs when you have a heap problem.
Something like:
int *a = new char[1];
a[500] = 0;
then later, on totally unrelated object you will get an error on delete or new.
You haven't shown us where paObject is declared ... or where it's (re)initialized ...
... but that's almost certainly the problem.
If you haven't initialized it to NULL, it might contain random garbage. In which case it won't evaluate to NULL, and Bad Things will happen.
Similarly, if don't explicitly reset it to NULL, then Bad Things will also happen.
Of course, we don't even know if paObject is an array (allocated with "new []") ... because you haven't shown us.
BOTTOM LINE:
1) Make sure paObject is initialized before you use it, and correctly initialized before you re-use it.
2) If you treat it as an array object, make sure it's initialized as an array object
3) You also need to be careful about the differences between "Object", "Object references" (&Object or Object *), arrays of Objects. In particular, you need to consider when you're passing a reference to an existing object, or when you're (perhaps unintentially) creating a new object.
These links should help:
http://cplus.about.com/od/learning1/ss/constructors.htm
http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm
==================================================================
ADDENDUM:
It sounds like the error Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) is occurring because you're overwriting your array.
Object* paObject = new Object[1] // This is really easy to overwrite!
I don't see where in the code you're writing to paObject (or writing to some alias of paObject), but I'm almost certain that's the problem.
IMHO...
I am attempting to dynamically allocate memory to the heap and then delete the allocated memory. Below is the code that is giving me a hard time:
// String.cpp
#include "String.h"
String::String() {}
String::String(char* source)
{
this->Size = this->GetSize(source);
this->CharArray = new char[this->Size + 1];
int i = 0;
for (; i < this->Size; i++) this->CharArray[i] = source[i];
this->CharArray[i] = '\0';
}
int String::GetSize(const char * source)
{
int i = 0;
for (; source[i] != '\0'; i++);
return i;
}
String::~String()
{
delete[] this->CharArray;
}
Here is the error I get when the compiler tries to delete the CharArray:
0xC0000005: Access violation reading location 0xccccccc0.
And here is the last call on the stack:
msvcr100d.dll!operator delete(void * pUserData) Line 52 + 0x3 bytes C++
I am fairly certain the error exists within this piece of code but will provide you with any other information needed. Oh yeah, using VS 2010 for XP.
Edit: Heres my String.h
// String.h - string class
#pragma once
#define NOT_FOUND -1
class String
{
public:
String();
String(char* source);
static int GetSize(const char * source);
int Find(const char* aChar, int startPosition = 0);
~String();
private:
char* CharArray;
int Size;
};
Change your default ctor; given the error you're getting, the delete call is trying to delete a pointer that has never been initialized.
String::String() : Size(0), CharArray(NULL) {}
Also, beware of the "copy constructor". You might want to make it private just to be sure you're not triggering it implicitly. (It doesn't need to be implemented if you don't intend to call it, just stick the function prototype into your class definition.) Might as well similarly "disable" the assignment operator.
class String
{
// other stuff
private:
String(String&);
String& operator=(String&);
};
This addition fulfills the "Rule of Three," which says that if any class needs a destructor, a copy constructor, or an assignment operator, it probably needs all three.
Edit: see http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29
String::String(): CharArray( 0 ) {}
You're not initializing CharArray in every constructor, so in some cases you're deleting an uninitialized pointer.
You have multiple constructors, but only 1 of them calls new. Your destructor always calls delete so there is your error.
I think #dash-tom-bang is correct. You're probably copying String and then deleting its data twice. I'll keep my old answers here for reference, though.
You're going to need to post the code that uses String, but I can notice a few problems here:
What if source is NULL in the constructor? Immediately you have a Null Pointer Exception. What's worse, if you get this exception, the destructor will attempt to delete memory that was never allocated. This could cause the error described above if you're using try...catch.
GetSize should not be a member function of String because it doesn't use any member variables. At the very least it should be static.