I have two classes Display and Snake.
With the Display class I hols some functionality that involves creating buffer and etc.
I'm trying to do something that seem logical to me but apparently not to the compiler
cSnake.h
class Snake
{
public:
Snake();
void printSnake();
~Snake();
private:
Display* display;
};
cSnake.cpp
Snake::Snake() {}
void Snake::printSnake() {
display->PrintCharecter(40, 15, L" Hello World ");
}
Snake::~Snake() {}
This is the Display class
Class Display{
public:
void CreateScreenBuffer();
void DisplayFrame();
void PrintCharecter(int x, int y LPCWSTR text);
private:
int nScreenWidth;
int nScreenHeight;
wchar_t *screen;
}
// The function that I try to call
void Display::PrintCharecter(int x, int y, LPCWSTR text) {
wsprintf(&screen[y* nScreenWidth + x], text); // exception is thrown here
}
Calling it in the main
Snake snake
snake.printSnake();
Then it throws unhanded exception that.
Being NULL pointer. I bit confused here, which one the NULL pointer is it the function call or the array screen?
The error is that the Display pointer points to nothing, which is an uninitialized pointer. A pointer only stores the address of the memory, not the actual memory. Therefore you have only created a pointer, but not the memory it points to on the heap. This means that in your constructor, you should create a new display object on the heap and assign that to your pointer.
Snake::Snake()
{
display = new Display;
}
This will give you your expected behaviour.
It's also important to note that you must delete the memory the pointer points to otherwise it will just float there until the program ends. Therefore your Snake destructor should delete display:
Snake::~Snake()
{
delete display;
}
Related
Following my understanding of C++ convention, I have:
class BlockRepresentation : public FPRepresentation
{
private:
class Block
{
public:
int id;
int fpDimensions;
int* position; // pointers in question
int* blockDimensions; // pointers in question
~Block();
};
std::vector<Block> all_blocks;
public:
BlockRepresentation( int count, int dimensions, int volumn[] );
void AddBlock( int id, int position[], int dimensions[] );
std::string ToGPL();
};
where new blocks are created in AddBlock:
void BlockRepresentation::AddBlock( int id, int position[],
int dimensions[] )
{
Block newBlock;
newBlock.id = id;
newBlock.fpDimensions = fpDimensions;
newBlock.position = new int[fpDimensions]; // pointers in question
newBlock.blockDimensions = new int[fpDimensions]; // pointers in question
for (int i = 0; i < fpDimensions; ++i)
{
newBlock.position[i] = position[i];
newBlock.blockDimensions[i] = dimensions[i];
}
all_blocks.push_back( newBlock );
}
so I have the following destructor:
BlockRepresentation::Block::~Block()
{
delete[] position;
delete[] blockDimensions;
}
but then I get:
rep_tests(11039,0x7fff71390000) malloc: *** error for object 0x7fe4fad00240: pointer being freed was not allocated
Why should I not delete[] the 2 pointers here?
As was pointed out in the comments, you violated the rule of three, and the violation is very obvious:
{
Block newBlock;
// snip
all_blocks.push_back( newBlock );
}
When this function returns, the newBlock object goes out of scope, and its destructor will delete all the newed arrays.
But you push_back()ed this object. This constructs a copy of the object into the vector. Because your Block does not define a copy constructor, the default copy-constructor simply makes a copy of all the pointers to the newed arrays.
If you somehow manage to avoid dereferencing the no-longer valid pointers, or you survived that experience, you're not of the woods yet. That's because, when the vector gets destroyed, and its Blocks get destroyed, their destructors will, once again, attempt to delete the same newed arrays that were already deleted once before.
Instant crash.
There is nothing wrong with your Block destructor. It is doing its job, which is releasing the memory that is pointed to by your two int * member variables. The problem is that the destructor is being called on the same pointer value multiple times, which results in a double-free error.
The entity that causes this is the std::vector<Block>, since a std::vector will make copies of your Block object, and your Block object is not safely copyable.
Since the member variables of Block that are pointers are position and blockDimensions, the most painless way to alleviate this issue is to use std::vector<int> instead of int *, as demonstrated by this sample program.
However, if you really wanted to use int *, you would need to implement a user-defined copy constructor. In addition, a user-defined assignment operator would complement the copy constructor. This is what is called the Rule of Three.
#include <algorithm>
//...
class Block
{
public:
int id;
int fpDimensions;
int *position;
int *blockDimensions;
Block() : position(nullptr), blockDimensions(nullptr),
id(0), fpDimensions(0) {}
~Block()
{
delete [] position;
delete [] blockDimensions;
}
Block(const Block& rhs) : id(rhs.id), fpDimensions(rhs.fpDimensions),
position(new int[rhs.fpDimensions]),
blockDimensions(new int[rhs.fpDimensions])
{
std::copy(rhs.position, rhs.position + fpDimensions, position);
std::copy(rhs.blockDimensions, rhs.blockDimensions + fpDimensions,
blockDimensions);
}
Block& operator=(const Block& rhs)
{
Block temp(rhs);
std::swap(temp.position, position);
std::swap(temp.blockDimensions, blockDimensions);
std::swap(temp.id, id);
std::swap(temp.fpDimensions, fpDimensions);
return *this;
}
};
See the live sample here.
See all of the hoops we had to jump through to get the Block class to behave correctly when used within a std::vector, as opposed to simply using std::vector<int>?
I have a question regarding how to correctly delete structs and it's respective pointers declared inside.
I have extracted an example from a project i have running and it doesn't seem to work correctly, the code doesn't crash but it seems i have some "memory leaks". I'm not sure that is the right wording. The issue is that the values is not really reset and are kept in the memory next time i initiate a class.
Sudocode below:
Header:
ProgramHeader.h
class ClassA : public publicClassA
{
public:
ClassA(void);
virtual ~ClassA();
private:
struct ApStruct{
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} fR;
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} f1kHz;
};
ApStruct* GetApStruct;
}
Program:
Program.cpp
#include "ProgramHeader.h"
ClassA::~ClassA()
{
//EDIT i did a typo my looks like this:
//delete ApStruct; //Wrong code
delete GetApStruct; //Corrected - however still not working
}
main()
{
GetApStruct = new ApStruct();
//Do Code
}
Hope it all makes a bit sense,
EDIT:
I have updated one wrong line in the code - however the question still remains the same. I will have a look at below to understand before i implement a solution.
EDIT 24/10/2015
I have been trying out a few of the suggestions below and im not able to find a solution to my issue, i must admit i also have difficulties to narrow it down what could cause it.
My code is part of a DLL. The code wraps some source code im not in control of, and therefore i have limited options how i init using constructors and new on pointers.
The reason i still think i have memory leak issues is if i add a "magic float" in my code the output of my functions change, even the float is not used anywhere - it is just declared.
I get different results when:
Calling InitCode - once!
then i will call CallCode multiple time - doing my calculations
Destruct the instance of the class
When i repeat the above again i get different result from the first time i run the code but afterwards it stays the same.
If i include the magic line all seems to work???
Updated SudoCode:
Program.cpp
#include "ProgramHeader.h"
ClassA::~ClassA()
{
//EDIT i did a typo my looks like this:
//delete ApStruct; //Wrong code
delete GetApStruct; //Corrected - however still not working
}
main()
{
void initCode()
{
GetApStruct = new ApStruct();
float InitValue = 0.F
//Magic line:
float magicLine = 123456.f; //If this line is commented out i get different results in my code
//End Magic Line
fr.refA[0] = &InitValue;
fr.refA[0] = &InitValue;
fr.refA[0] = &InitValue;
fr.pVarA = &InitValue;
...
}
void CallCode()
{
float CallValue = 123.F
//Magic line:
float magicLine = 123456.f; //If this line is commented out i get different results in my code
//End Magic Line
fr.refA[0] = &CallValue;
fr.refA[0] = &CallValue;
fr.refA[0] = &CallValue;
fr.pVarA = &CallValue;
...
}
}
Thanks guys for you support,
Thomas
I would recommend something like the following for allocation and cleanup...
#include <iostream>
using namespace std;
class ClassA
{
public:
ClassA(void);
virtual ~ClassA();
private:
struct ApStruct {
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} fR;
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} f1kHz;
};
ApStruct* GetApStruct;
};
ClassA::ClassA(void) {
GetApStruct = new ApStruct{};
GetApStruct->fR.refA[0] = new float{ 1.f };
GetApStruct->fR.refA[1] = new float{ 2.f };
GetApStruct->fR.refB[0] = new float{ 3.f };
GetApStruct->fR.refB[1] = new float{ 4.f };
GetApStruct->fR.pVarA = new float { 0.f };
// do same for struct f1kHz
// ...
cout << "Construction" << endl;
}
ClassA::~ClassA()
{
if (GetApStruct != nullptr) {
if (GetApStruct->fR.refA[0] != nullptr) {
delete GetApStruct->fR.refA[0];
GetApStruct->fR.refA[0] = nullptr;
}
if (GetApStruct->fR.refA[1] != nullptr) {
delete GetApStruct->fR.refA[1];
GetApStruct->fR.refA[1] = nullptr;
}
if (GetApStruct->fR.refB[0] != nullptr) {
delete GetApStruct->fR.refB[0];
GetApStruct->fR.refB[0] = nullptr;
}
if (GetApStruct->fR.refB[1] != nullptr) {
delete GetApStruct->fR.refB[1];
GetApStruct->fR.refB[1] = nullptr;
}
if (GetApStruct->fR.pVarA != nullptr) {
delete GetApStruct->fR.pVarA;
GetApStruct->fR.pVarA = nullptr;
}
// do same for struct f1kHz
// ...
// finally
delete GetApStruct;
GetApStruct = nullptr;
}
cout << "Destruction" << endl;
}
int main() {
{
ClassA a;
}
system("pause");
return 0;
}
Well when you create a structure/class object, it holds the variables and pointers in that object memory area( say an object occupies some space in memory. Let's call it a box). Those pointer variables when initialized with new() or malloc(), are given space outside of that box in which the object's data resides. Those pointers now point to some memory area that is outside of that object's memory area. Now when the object is destructed, that space occupied by object (as we called it the box) is destroyed accompanying the pointer variables. The memory area pointed by the pointers is still in there in program/process memory area. Now we have no clue what's it address or where it lies. That's called memory leak. To avoid this situation, we need to de-allocate the memory referenced by pointers using delete keyword. We're free to go now. I tried to illustrate it with a simple graphic below. ObjectA box illustrates the area occupied by it in the memory. Note that this container/box holds the local varialbes including pointer. The pointer points to some memory location, say 0xFFF... and is illustrated by green line. When we destroy ObjectA, It simply destroys everything in it including 0xFFF address. But the memory located on 0xFFF is still allocated in the memory. A memory leak.
In your destructor, de-allocate memory explicitly using delete keyword. Whoa! We saved the memory.
From Wikipedia Resource Acquisition Is Initialization
Resource Acquisition Is Initialization (RAII) is a programming idiom used prominently in C++. In RAII, resource acquisition is done during object creation, by the constructor, while resource release is done during object destruction, by the destructor. If objects are destroyed properly, resource leaks do not occur.
So you can new the memory used for pointers in constructor and release them in destructor:
ClassA::ClassA(void) {
GetApStruct = new ApStruct;
GetApStruct->fR.refA[0] = new float{ 1.f };
GetApStruct->fR.refA[1] = new float{ 2.f };
}
ClassA::~ClassA(void) {
delete []GetApStruct->fR.refA;
delete GetApStruct;
}
Alright, let me be direct:
If you are using new or delete, you are doing it wrong.
Unless you are an experienced user, or you wish to implement a low-level side project, do not ever use new and delete.
Instead, use the existing standard classes to handle memory ownership, and just avoid heap-allocation when it is unnecessary. As a bonus, not only will you avoid memory leaks, but you will also avoid dangling references (ie, using memory after deleting it).
class ClassA : public publicClassA {
public:
private:
struct ApStruct{
struct
{
float refA[2];
float refB[2];
float pVarA;
} fR;
struct
{
float refA[2];
float refB[2];
float pVarA;
} f1kHz;
};
ApStruct GetApStruct;
}
And yes, in your case it is as simple as removing the pointers. Otherwise, if you want dynamic arrays (ie, arrays whose length is unknown at compile-time) use std::vector.
I have a pointer code as follows :
class NsObject : public TclObject, public Handler {
public:
NsObject();
virtual ~NsObject();
virtual void recv(Packet*, Handler* callback = 0) = 0;
virtual void recv(Packet* p, const char* s);
}
NsObject* uptargetTX;
NsObject* uptarget_;
void NsObject::recv(Packet *p, const char*)
{
Packet::free(p);
}
if (NodeType_ == TX) {
uptarget_->recv(ppp, (Handler*) 0);
*uptargetTX = *uptarget_; //in this line error happens
}
I want to pass/copy the pointer uptarget_ to uptargetTX by using *uptargetTX = *uptarget_; but something goes wrong
segmentation fault (core dumped)
Then I change to uptargetTX = uptarget_; but same error occurs. How to remove this error ?
uptargetTX and uptarget_ are unininitialized, so they point to random memory locations, so access causes a segmentation fault. Depending on what you are trying to do, you probably have to allocate memory first for example like this: NsObject* uptargetTX = new NsObject
I have no idea of what your code does but this
NsObject* uptarget_;
uptarget_->recv(ppp, (Handler*) 0); <- dereference the pointer
is wrong in the first place: you need to initialize that pointer to something valid before.
The rest is also wrong for the same reason.
I have a strange problem in C++. An address of a Boolean gets "destroyed" but it doesn't get touched. I know that there are better ways to accomplish what I try to do, but I want to know what I do wrong.
I have a main class; this main class contains a vector of another class. There is a strange problem when a new instance gets created of this object.
This is how my code works:
There will start a thread when the constructor gets called of the β2ndβ object. This thread gets as Parameter a struct. This is the struct:
struct KeyPressData
{
vector<bool> *AutoPressStatus;
vector<int> *AutoPressTime;
bool * Destroy;
bool * Ready;
};
The struct gets filled in the constructor:
MultiBoxClient::MultiBoxClient()
{
//init data
DestroyThread = new bool;
ReadyThread = new bool;
AutoThreadData = new KeyPressData;
//Reseting data
*DestroyThread = false;
*ReadyThread = false;
//KeyPressData configurating
AutoThreadData->AutoPressStatus = &AutoPressStatus;
AutoThreadData->AutoPressTime = &AutoPressTime;
AutoThreadData->Destroy = DestroyThread;
AutoThreadData->Ready = ReadyThread;
//Start the keypress thread
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)AutoKeyThread,AutoThreadData,NULL,NULL);
}
This is the defenition of MultiBoxClient:
class MultiBoxClient
{
private:
HWND ClientHandle;
vector<bool> KeyPresses;
vector<bool> AutoPressStatus;
vector<int> AutoPressTime;
KeyPressData * AutoThreadData;
bool * DestroyThread;
bool * ReadyThread;
public:
MultiBoxClient();
MultiBoxClient(HWND Handle);
~MultiBoxClient();
void EditClient(HWND Handle);
void SendKeypress(vector<bool> KeyStatus);
void SendKeyCombination(unsigned int id);
void AutoCast(int Key,unsigned int Time,bool status);
bool IsAlive();
};
MultiBoxClient is created this way:
int main()
{
MultiboxControler * MainControler = new MultiboxControler;
while(true)
{
Sleep(1000);
}
delete MainControler;
return false;
}
As long as the constructor is running will the program run fine. But when the constructor closes the address of the AutoThreadData->Destroy will get corrupted. The program will crash when I call the value of the pointer.
β
void WINAPI AutoKeyThread(void * ThreadData)
{
KeyPressData * AutoThreadData = (KeyPressData*)ThreadData;
while(true)
{
if(*AutoThreadData->Destroy == true) //CRASH
{
*AutoThreadData->Ready = true;
return;
}
Sleep(100);
}
}
What did I test:
I logged the address of the AutoThreadData and the AutoThreadData->Destroy when the constrcutor is running and clossed; the AutoThreadData address is equal to AutoThreadData when the constructor is closed. So there is no problem here.
The address of AutoThreadData->Destroy gets destroyed when the constructor is closed. But how can this happen? The Boolean is on the heap and the KeyPressData struct (AutoThreadData) is on the heap.
Destroy before: 00A85328
Destroy after: FEEEFEEE
Can someone maby explain why this crash?
I know that I can send a pointer to my class to the thread. But I want to know what goes wrong here. That way I can learn from my mistakes.
Could someone help me with this problem?
I guess that you made a mistake with the vector, use a class pointer, instead of the class itself, like this:
vector<class*> //instead of vector<class>
0xFEEEFEEE is an indication of freed memory. That is, you AutoThreadData was deleted, and it was not on your worker thread which is in endless loop. So, it has to be your main thread and perhaps destructor, which you did not show.
Whereever you destroy/free your KeyPressData instance, comment this out or set a breakpoint there to find out where it is taking place.
This Code returns an error on the delete [] placard_; call
void Protestor::destroy() { //Free's caller Protestor's dynamic memory
delete [] placard_;
}
This code does not.
void Protestor::destroy() { //Free's caller Protestor's dynamic memory
delete placard_;
}
This goes against my class notes, which state to ALWAYS call
delete []
rather than
delete
What is the explanation for this behaviour? Under what conditions must 'delete' be called instead of 'delete []'?
Here is the Definition for the Protester and Sign classes.
class Protester
{
public:
Protester(string name, string signSlogan, int signHeight, int signWidth,
int rcmp_file = 0 );
string getName() const;
Sign getPlacard() const;
void changePlacard( string newSlogan, int newHeight, int newWidth);
void setRCMPfile(int RCMP_file);
int getRCMPfile() const;
//Big Three
Protester(const Protester& other); //Copy Constructor
~Protester(); //Destructor
Protester& operator= (const Protester& other); //Assignment Constructor
private:
// name of the Protester
string name_;
// a sign the protester is wielding
Sign* placard_;
// the RCMP file number tracking this person (zero means no RCMP report)
int rcmp_file_;
//Big Three Helper Functions
void copy(const Protester& other); //Performs Deep Copy of const Protester&
void destroy(); //deletes [] placard_
//sounds better then cleanup, in my humblest of opinions.
};
class Sign
// a class representing information about signs/placards
{
public:
// constructor to initialize sign text and dimensions
Sign(string statement, int height, int width);
// return sign text
string getStatement() const;
//return sign height
int getHeight() const;
//return sign width
int getWidth() const;
// change sign text
void setStatement(string statement);
// change sign dimensions
void setSize(int height, int width);
private:
// the text of the sign
string statement_;
// dimensions of the sign
int height_;
int width_;
};
This goes against my class notes, which state to ALWAYS call delete [] rather than delete
No that's wrong. You have to pair calls to new and delete and calls to new[] and delete[].
Note:
But that's not how you should to that in modern C++. Use std::shared_ptr or std::unique_ptr instead. This is usually a much safer choice. Calls to new/new[] should be nearly always enclosed in smart pointer and delete should not be needed at all. Very few exceptions.
When you use new Object() you should use delete
When you use new Object[] (and array of objects) you should use delete[]
delete[] is called to free a dynamically allocated array: new type[]
delete is called to free a dynamically allocated object: new type
See delete C++ Wikipedia page.
Note, that if the destroy() function is invoked twice an attempt will be made to free an already deleted object as placard_ is not NULLed after the delete (if delete is called on a NULL pointer it has no effect).
You use operator delete[] only when you're allocating with operator new[]. Furthermore, you should try to use containers (vector, list, ..) and smart pointers (unique_ptr, shared_ptr).