I have a problem with my code. I want to show different windows one by one by clicking the "Next" button to show the next one like this:
int i = 0;
do {
auto polyLines = new ExportPolyLines(nodeNames);
polyLines->show();
if (!polyLines->isVisible()) {
i++;
}
} while (i < 3);
The code compiled but did not work!
Can anyone help me about this?
As an improvement to your comment I would suggest that you fix the memory leak.
if (_logIsSelected)
{
for (int i = 0; i < _selectedWellLogs.size(); i++)
{
auto exportLogsData = new ExportsLogs(_selectedWellLogs[i], _wellLogsName[i], _folder);
exportLogsData->exec();
delete exportLogsData; // Free the memory that has been used for ExportLogs
exportLogsData = nullptr; // Not really necessary here, but good practice
}
}
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 1 year ago.
Improve this question
I have a very insidious issue with two dynamically allocated and reallocated multidimensional arrays, defined as follows:
int *pRawVals[20][181];
and
int *pMaxPlaneRawPlanes[20][46];
These are allocated in a single function: (code condensed for clarity)
...
// iNlat and iNVer bounds checked and OK
for (int lat = 0; lat < iNlat; lat++)
{
pData->pBlendedRawPlanes[lat] = new long long[1 * (iNver + 1)];
for (int sensor = 0; sensor < 20; sensor++)
{
pData->pRawVals[sensor][lat] = new int[1 * (iNver + 1)];
for (int vert = 0; vert <= iNver; vert++)
{
pData->pRawVals[sensor][lat][vert] = SENSOR_UNREAD;
} // end for
} // end for
} // end for
...
for (int sensor = 0; sensor < 20; sensor++)
{
delete[] pData->strayVals[sensor];
pData->strayVals[sensor] = new int[1 * (iNver + 1)];
for (int vert = 0; vert < iNver + 1; vert++)
{
pData->strayVals[sensor][vert] = SENSOR_UNREAD;
} // end for
for (int lat = 0; lat < 46; lat++)
{
pData->pMaxPlaneRawPlanes[sensor][lat] = new int[361];
// for (int iFillMem = 0; iFillMem < 361; iFillMem++)
for (int vert = 0; vert < iNver; vert++)
{
pData->pMaxPlaneRawPlanes[sensor][lat][vert] = SENSOR_UNREAD;
} // end for
} // end for
} // end for
... and deallocated in another function:
for (int lat = 0; lat < pData->iNUserLats; lat++) // iNUserLats <= 181
{
for (int sensor = 0; sensor < 20; sensor++)
{
if (pData->pRawVals[sensor][lat] != NULL)
{
delete[] pData->pRawVals[sensor][lat];
pData->pRawVals[sensor][lat] = NULL;
} // end if
} // end for
}
...
for (int sensor = 0; sensor < 20; sensor++)
{
for (int lat = 0; lat < 46; lat++)
{
if (pData->pMaxPlaneRawPlanes[sensor][lat] != NULL)
{
delete[] pData->pMaxPlaneRawPlanes[sensor][lat];
pData->pMaxPlaneRawPlanes[sensor][lat] = NULL;
} // end if
} // end for
} // end for
Hope I got enough of the code posted. At any rate, when deallocating pMaxPlaneRawPlanes on a second pass through the code, it turns out that certain elements of that array overlap elements of pRawVals and the deallocation causes a crash - appears that those locations may have been freed previously but I can't seem to point the finger at exactly how it's happening.
Any hints on how to narrow that kind of thing down? I run development on Windows 7 Ultimate 64 bit, but the app is compiled for 32 bit.
Thanks
You may go out of range in any of your array, or you may go out of range elsewhere.
If you are using Visual Studio 2019, or you are using gcc or clang, you can give ASan (Address Sanitizer) a try. (VS2019 link)
Otherwise you can try Application Verifier with Full Heap check enabled.
It is also possible to use custom allocation and allocate memory the way that it will access violation on out of bounds, even if off by one. It is essentially duplicating Application Verifier for particular allocations.
Using std::array or std::vector recommended in comments will also help making fewer errors that lead to heap corruption in the first place. vector manages deallocations automatically, and also in debug builds may have checks for out-of-range errors.
I have an array of space object (my thing) that I need to reduce but keep the same name in order to handle some collisions. I set my array up like:
ufo** ufoAr = new ufo*[numberOfUfos];
for (int i=0; i<numberOfUfos; i++) {
ufoAr[i] = new ufo(randomIntBetween(1630, 70), randomIntBetween(860, 45));
}
and when i detect a collision I want to resize my array with two less and delete the two specific elems of array. like here:
//look through all the ufoAr[]
for (int i=0; i<numberOfUfos; i++) {
//look through ufoAr[] again to see other objects
for(int j=0; j<10; j++) {
//if the same
if (i==j){ continue; }
else {
//find a collision
if(ufoAr[i]->collision(ufoAr[j]->sp)) {
//Array::Resize(ufoAr, numberOfUfos-2);
//numberOfUfos = numberOfUfos - 2;
// ------ TRY TO RESIZE ARRAY TO -2 BUT SAME NAME WITHOUT iTH AND jTH ELEM
ufoAlive[i] = false;
ufoAlive[j] = false;
}
}
}
}
I would greatly appreciate any help on resizing the array, thanks in advanced. I am really struggling and need another opinion. thanks
Jack
To do this, you will need to FIRST create a new array, e.g.
ufo** ufoArTmp = new ufo*[numberOfUfos-2];
then copy the contents [you want to keep] of ufoAr into ufoArTmp. Once that is done, you do delete [] ufoAr, and finally ufoAr = ufoArTmp; to update the original pointer. do NOT delete ufoArTmp at this point, as it's the same value as is now in ufoAr, and you want to keep that, right.
Obviously pay special attention to numberOfUfos being less than 2 when you start... ;)
Edit, in reading through the other code:
Don't do this:
if (i==j){ continue; }
else {
much better:
if (i!=j) {
The simplest way to do this is to use std::vector and let that handle the resizing for you.
cplusplus.com reference
cppreference page
I am using a double pointer but when I try to delete it it causes Heap Corruption: CRT detected that the application wrote to memory after end of heap. It "crashes" inside the destructor of the object:
Map::~Map()
{
for(int i = 0; i < mTilesLength; i++)
delete mTiles[i];
delete[] mTiles;
}
mTiles is declared something like this:
Tile **mTiles = NULL;
mTiles = new Tile *[mTilesLength];
for(int i = 0; i < mTilesLength; i++)
mTiles[i] = new Tile(...);
If notable mTiles is a object of "Tile" which inherits from a object "Sprite" all 3 destructors are set as virtual (map, tile, sprite), not sure if that makes any difference but seemed to work until now.
The code you posted does not seem to have any problems in it. I created a simple, self contained, compiling (and correct) example from it:
struct Tile {int x; Tile():x(7) {}};
struct Map {
Tile **mTiles;
int mTilesLength;
Map(int TilesLength_);
~Map();
};
Map::~Map()
{
for(int i = 0; i < mTilesLength; i++) {
delete mTiles[i];
}
delete[] mTiles;
}
Map::Map(int TilesLength_):
mTiles(),
mTilesLength(TilesLength_)
{
mTiles = new Tile *[mTilesLength];
for(int i = 0; i < mTilesLength; i++) {
mTiles[i] = new Tile();
}
}
int main() {
Map* m = new Map(1000);
delete m;
}
I compiled and ran it <- link, and nothing bad was noticed.
Your problem lies in code you have not shared with us. In order to find the code that is causing the problem and ask the right question, go here: http://sscce.org/
Then take your code and start trimming parts off it until the code is simple, yet still demonstrates your heap corruption. Keep copies of each version as you trim away irrelevant code so you don't skip over the part where the problem occurs (this is one of the many reasons you want a version control system even on your personal projects).
I want to create a SDL-based Hanoi Tower Game, but before I proceed to writing "engine", I wanted to test my Hanoi in a console. Surprisingly, it turned out to be quite buggy.
CTower tower[3];
tower[0] = CTower(3);
tower[1] = CTower(3);
tower[2] = CTower(3);
init(&tower[0]); //prepare first tower
tower[0].Print();
This piece of code should create 3 arrays (of size 3) and fill 'em with 0 (zeros). Then, in init(), I prepare the first tower (fill it with vaild discs). However simple may it seem, my application halts on printing and doesn't fill the remaining arrays (with 0). What's strange, function init() works just fine.
I would appreciate any help.
Here's some code to check:
class CTower {
uint16 *floors, floorsNum;
void Init();
public:
(...) //definitions, probably of zero importance
};
void CTower::Init() {
//private member, filling with zeros
for (uint16 i = 0; i < floorsNum; i++)
floors[i] = 0;
}
CTower::CTower() {
//default initialiazer
floors = NULL;
floorsNum = 0;
}
CTower::CTower(uint16 nfloors) {
floors = new uint16[nfloors];
floorsNum = nfloors;
this->Init();
}
CTower::~CTower() {
delete[] floors;
floorsNum = 0;
}
void CTower::Print() {
if (floorsNum == 0) printf("EMPTY TOWER!");
else
for (uint16 i = 0; i < floorsNum; i++)
printf("%d\n", floors[i]);
}
void init(CTower *tower) {
//a friend method of CTower
for (uint16 i = 0; i < tower->floorsNum; i++)
tower->floors[i] = i+1;
}
My application source: https://rapidshare.com/files/2229751163/hanoi-tower.7z
Problem is with your initialisation and allocation of your class. It seems you have forgotten that Resource Acquisition is Initialisation.
You are facing a free corruption : you call delete[] on a not allocated attribute.
You have this constructor :
CTower::CTower() {
//default initialiazer
floors = NULL;
floorsNum = 0;
}
Which does NOT allocates memory but which is destroyed with :
CTower::~CTower() {
delete[] floors;
floorsNum = 0;
}
A simple way to fix your program is to allocate directly with the working constructor :
int main(void) {
CTower tower[3] = { CTower(3), CTower(3), CTower(3) };
init(&tower[0]);
tower[0].Print();
printf("\n");
tower[1].Print();
return 0;
}
But it would be far better to also fix your Class, either in Destructor or in Constructor part.
Unless you have been specifically asked not to use a std::vector then I would consider changing your code to use one as it makes life a lot simpler.
With regards to your specific code example. You are going to have problems due to the lack of a copy constructor and assignment operator as the defaults generated by the compiler are not going to be suitable for your class.
I would also consider getting rid of the friend function void init(CTower *tower) as this really isn't good practice.
I would provide a code example but this question is tagged as "Homework" so I will let you do the research yourself.
CString dance[] = {L"Atb", L"Tiesto", L"Madonna", L"Paul van Dyk", L"Armin van Burren", L"Jennifer Lopez"};
for(int i = 0; i < m_ItemsListBox.GetCount(); ++i)
{
CString item;
int length = m_ItemsListBox.GetTextLen(i);
m_ItemsListBox.GetText(i, item.GetBuffer(length));
for(int j = 0; j < sizeof(dance)/sizeof(*dance); ++j)
{
if(item != dance[j])
{
m_ItemsListBox.DeleteString(i);
}
}
}
I'm trying to remove from a listbox(m_ItemsListbox) all elements that are not part from the CString array. But how I coded it doesnt work, because if the first element its different it will delete it without searching the entire array.
Doesn't seemed like a hard task but I really have no idee how to do it. I think one way should be to use a CList instead of the array because it has a find() method, but I don't like it because I have to manually add all the elements, do you guys have another idee? Or the CList solution is the only one ?
Sorry, I'm a MFC begginer. Thanks for your time.
Hmmm I wouldn't be comfortable deleting things from the list box while iterating through the items in the listbox seems to be asking for problems down the line.
Honestly you could do something like this, I've just whipped together - construct a list of all the item indexes you want to remove and remove them at the end.
CList<int, int> ListIndexItemsToRemove;
for(int i = 0; i < m_ItemsListBox.GetCount(); ++i)
{
CString item;
int length = m_ItemsListBox.GetTextLen(i);
m_ItemsListBox.GetText(i, item.GetBuffer(length));
bool isMatchFound = false;
for(int j = 0; j < sizeof(dance)/sizeof(*dance); ++j)
{
if(item == dance[j])
{
isMatchFound = true;
}
}
if (!isMatchFound)
ListIndexItemsToRemove.AddHead(i);
}
for(int i = 0; i < ListIndexItemsToRemove.GetCount(); ++i)
m_ItemsListBox.DeleteString(ListIndexItemsToRemove.GetAt(ListIndexItemsToRemove.FindIndex(i));
but - it may be better to clear the whole list and refill it everytime something changes, as Martin says (if it doesn't affect anything.
For dynamic lists I tend to store data in its own variable and clear/re-populate the list when that data changes. Especially as the list gets bigger re-adding the strings tends to be much faster than doing searches through the list and/or original source.