Erasing a pointer from a vector - c++

I'm trying to erase a pointer to an object, but I keep crashing the console (PS2), I don't get any errors due to the way the console is set up, so I'm not quite sure what is going on.
I've listed the two lines that error, this didn't error until I added these lines.
for(listIter = m_downDirectionList.begin(); listIter != m_downDirectionList.end(); listIter++)
{
Projectile* proj = dynamic_cast<Projectile*>(*listIter);
if (proj->getZWorldCoord() >= (defaultLevelDepth + zOffset))
{
proj->getPoolOwner()->releaseAProjectile(proj);
//(*listIter) = NULL; // THIS ERRORS, also tried = 0.
//listIter = m_downDirectionList.erase(listIter); // THIS ALSO ERRORS
}
else
{
(*listIter)->update(camera, zOffset);
}
}
What am I doing wrong?
Thanks.
EDIT:
Clarification, just having this line.
listIter = m_downDirectionList.erase(listIter);
this also errors.

for(listIter = m_downDirectionList.begin(); listIter != m_downDirectionList.end(); )
{
Projectile* proj = dynamic_cast<Projectile*>(*listIter);
if (proj->getZWorldCoord() >= (defaultLevelDepth + zOffset))
{
proj->getPoolOwner()->releaseAProjectile(proj);
listIter = m_downDirectionList.erase(listIter);
}
else
{ //m_downDirectionList[p]->update(camera, zOffset);
(*listIter)->update(camera, zOffset);
listIter++
}
}

m_downDirectionList.erase (listIter);

Related

If else not working in android inside for and while loop

public void LoadRoutine() {
TableRow tbrow0 = new TableRow(getActivity());
//String[] mStrings = new String[9];
tbrow0.setBackgroundColor(Color.parseColor("#FFFFFF"));
tbrow0.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));
for (String c : TimeSlotSummer) {
TextView tv0 = new TextView(getActivity());
tv0.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
tv0.setGravity(Gravity.CENTER);
tv0.setTextSize(12);
tv0.setHeight(40);
tv0.setWidth(76);
tv0.setBackgroundColor(Color.parseColor("#FFFFFF"));
tv0.setTextColor(Color.parseColor("#000000"));
tv0.setPadding(1, 1, 1, 1);
tv0.setText(c);
tv0.setBackgroundColor(R.id.tableRowid);
tbrow0.addView(tv0);
}
tableLayout.addView(tbrow0);
String dept = GlobalClass.userDepartment;
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(getActivity());
databaseAccess.Open();
String faccode = GlobalClass.faculty_code;
Cursor cRoutine = databaseAccess.getRoutine("Sunday",dept);
if (cRoutine.getCount() == 0) {
Toast.makeText(getActivity(),"No Data in Table",Toast.LENGTH_LONG).show();
}
else{
while (cRoutine.moveToNext())
{
String[] mStrings = new String[10];
mStrings[0] = cRoutine.getString(2);
mStrings[1] = cRoutine.getString(4);
mStrings[2] = cRoutine.getString(5);
mStrings[3] = cRoutine.getString(6);
mStrings[4] = cRoutine.getString(7);
mStrings[5] = cRoutine.getString(8);
mStrings[6] = cRoutine.getString(9);
mStrings[7] = cRoutine.getString(10);
mStrings[8] = cRoutine.getString(11);
TableRow tbrow1 = new TableRow(getActivity());
tbrow1.setBackgroundColor(Color.parseColor("#FFFFFF"));
tbrow1.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));
for (String cls:mStrings) {
TextView tv1 = new TextView(getActivity());
tv1.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
tv1.setGravity(Gravity.CENTER);
tv1.setTextSize(12);
tv1.setWidth(75);
tv1.setHeight(37);
tv1.setBackgroundColor(Color.parseColor("#FFFFFF"));
tv1.setPadding(1, 1, 1, 1);
tv1.setBackgroundColor(R.id.tableRowid);
tv1.setText(cls);
tv1.setTextColor(Color.parseColor("#FF0000"));
if(cls.contains(faccode))
tv1.setTextColor(Color.parseColor("#000000"));
else
tv1.setTextColor(Color.parseColor("#FF0000"));
tbrow1.addView(tv1);
}
tableLayout.addView(tbrow1);
}
}
}
Inside the last for loop, without if-else, it works properly, but with if-else it is not working, that is apps shut down and mobile restart again.
Any one help me, I want to check some substring, then text color will change, otherwise color normal.
It would help if you posted a stack trace but if the crash occurs here:
if(cls.contains(faccode))
tv1.setTextColor(Color.parseColor("#000000"));
else
tv1.setTextColor(Color.parseColor("#FF0000"));
The only explanation is that you get a NullPointerException on cls because tv1 is obviously not null if it did not crash before.
Use this code instead:
if(cls != null && cls.contains(faccode))
tv1.setTextColor(Color.parseColor("#000000"));
else
tv1.setTextColor(Color.parseColor("#FF0000"));

dao property from vb to mfc

i have implemented vb functionality in c++ i have replace below logic in c++ but it is giving issue :
i have to convert from VB to c++ and the code in c++ is crashing when getting property.
Original VB code:
For Each loTDef In aoDBUser.TableDefs
Set loProp = Nothing
On Error Resume Next
Set loProp = loTDef.Properties("Description")
If Not loProp Is Nothing Then
If loProp.Value = TEMP_TABLE Then
End If
End If
Next
New C++ code:
CString test::Property()
{
//
// OVERVIEW:
// Get the value for the given Custom Property
//
DAOProperties *pColProp = NULL;
DAOProperty *pProp = NULL;
CDaoDatabase cDBase;
cDBase.Open(CV_GetUserDatabasePath(_T("TEST.mdb")));
CString strDbVer;
DAOProperties* pPrp = 0;
DAOProperty* pRev = 0;
try
{
if ( !cDBase.IsOpen() )
return(_T(""));
DAO_CHECK(cDBase.m_pDAODatabase->get_Properties(&pPrp));
if ( pPrp != 0 )
{
COleVariant varRevVal;
COleVariant varName(_T("Description"), VT_BSTRT);
DAO_CHECK(pPrp->get_Item(varName, &pRev));//crashing going to catch
if (pRev != 0)
{
DAO_CHECK(pRev->get_Value(&varRevVal));
pRev->Release();
pRev = 0;
}
pPrp->Release();
pPrp = 0;
strDbVer = V_BSTRT(&varRevVal);
}
}
catch (...)
{
}
cDBase.Close();
}
some how it is crashing in DAO_CHECK(pPrp->get_Item(varName, &pRev));
But I cannot figure out why this occurs.

Unable to delete a list element in C++

I am working on a small game and came across a big problem with lists.
Here's my code:
void cCollisionManager::checkCollision(cPlayer * pPlayer, std::list<cAsteroid*> *asteroidList, std::list<cShot*> *ShotList)
{
sf::FloatRect PlayerBox = pPlayer->getSprite()->getGlobalBounds();
for (auto it : *asteroidList) {
for (auto es : *ShotList) {
sf::FloatRect asteroidboundingBox = it->getSprite()->getGlobalBounds();
sf::FloatRect ShotBox = es->getSprite().getGlobalBounds();
if (asteroidboundingBox.intersects(ShotBox)) {
it = asteroidList->erase(it);
*pPlayer->pPunkte += 1;
std::cout << *pPlayer->pPunkte << std::endl;
}
if (asteroidboundingBox.intersects(PlayerBox)) {
if (*pPlayer->phealth >= 0.f)
*pPlayer->phealth -= 0.5f;
}
}
}
}
I used SFML and basically everything works. But if I want to delete the colliding asteroid and the shot, the programs exits with an error. In the if loop I tried to erase the object, but the compiler also gives an error saying that the argument type is not the same as the object type I am giving to it.
EDIT
I had another look at the other question, you recommended to me, but still I haven't found out how to solve that problem. So if I changed my code to a while loop, the game couldn't handle it, because the Collision Manager is actually called in every single Call of the SFML main loop. So it would just get stuck in my collision loop. So I changed my code a bit, but still, things are not working.
Don't modify sequences that are being enumerated with range-for. Use
iterators and the appropriate result of an erase. – WhozCraig
This is actually the answer to it. I did the mistake - using a for loop and not a while loop and so I had some big issues and bad construction ideas for my code - luckily everything now works!
Here is my final code:
auto it = asteroidList->begin();
auto es = ShotList->begin();
while (it != asteroidList->end()) {
sf::FloatRect PlayerBox = pPlayer->getSprite()->getGlobalBounds();
sf::FloatRect asteroidboundingBox = (*it)->getSprite()->getGlobalBounds();
while (es != ShotList->end())
{
sf::FloatRect ShotBox = (*es)->getSprite().getGlobalBounds();
if (asteroidboundingBox.intersects(ShotBox)) {
it = asteroidList->erase(it);
es = ShotList->erase(es);
std::cout << "Asteroid destroyed" << std::endl;
*pPlayer->pPunkte += 1;
std::cout << *pPlayer->pPunkte << std::endl;
}
if (es != ShotList->end())
es++;
}
if (asteroidboundingBox.intersects(PlayerBox))
{
if (*pPlayer->phealth > 3.f) {
*pPlayer->phealth -= 5.f;
it = asteroidList->erase(it);
}
else
*pPlayer->pBStateAlive = false;
}
if (it != asteroidList->end()) {
it++;
es = ShotList->begin();
}
}
}

CCFiniteTimeAction::getDuration() EXC_BAD_ACCESS when creating a CCSequence

I was able to run this code without getting an error on the iPhone simulator. However, when I run it on my iPhone, I am getting a EXC_BAD_ACCESS error. Here is the code:
CCAnimate * explosionAnimate = CCAnimate::create(explosionAnimation);
CCCallFuncN * callFuncN = CCCallFuncN::create(this,callfuncN_selector(GameLayer::removeChildFromParent));
CCFiniteTimeAction * explosionSequence = CCSequence::create(explosionAnimate, callFuncN);
CCSprite * explosionSprite = CCSprite::createWithSpriteFrameName("explosion_frame_1");
addChild(explosionSprite);
explosionSprite->setPosition(point);
explosionSprite->runAction(explosionSequence);
}
void GameLayer::removeChildFromParent(CCNode * child)
{
child->removeFromParent();
}
The error occurs when CCSequence::create(...) is called. Debugging through CCSequence::create(...)
CCFiniteTimeAction* CCSequence::create(CCFiniteTimeAction *pAction1, va_list args)
{
CCFiniteTimeAction *pNow;
CCFiniteTimeAction *pPrev = pAction1;
while (pAction1)
{
pNow = va_arg(args, CCFiniteTimeAction*);
if (pNow)
{
pPrev = createWithTwoActions(pPrev, pNow);
}
else
{
break;
}
}
return pPrev;
}
I am seeing that "createWithTwoActions" get's called twice. That doesn't seem right. On the 2nd call to "createWithTwoActions". The error occurs within CCFiniteTimeAction, specifically at the getDuration() inline function:
inline float getDuration(void) { return m_fDuration; }
Any ideas why this would be occurring?
I was able to resolve the issue by calling CCSequence::create() like:
CCSequence::create(explosionAnimate, callFuncN, NULL);
instead of:
CCSequence::create(explosionAnimate, callFuncN);
I'm guessing this has to do with the nature of CCFiniteAction pointers and C++ variable length arguments.

Segmentation fault occurs only under release configuration

For some odd reason, my application likes to break on me when I switch to release and run it outside of my debugger. Here's what works for me, and here's what doesn't
(Qt Creator is the IDE)
Debugging with debug configuration - ok
Running with debug configuration - ok
Debugging with release configuration - ok
Running with release configuration - application crash
My UI is one project, and the core for some stuff as a separate dependency. On Windows (compiling with MSVCC), I hit a menu button, which eventually calls down to a function. In that function, the app breaks on adding a new element to a vector. e.g:
str *x = new str();
str *y = new str();
/* ...set some of x & y's members... */
vector.push_back(x); // works fine
vector.push_back(y); // causes crash
If I comment out the line vector.push_back(y);, the app continues no problem until the app leaves the event scope (i.e. the end of OnMenuButtonClick). On OS X, it's similar to the issue of adding an element to a vector, except I have:
std::vector<foo *> SomeFunction()
{
std::vector<foo *> returningVector;
/* do stuff */
std::vector<foo *> goo = GetFooObjects();
for (int i = 0; i < goo.size(); i++)
{
returningVector.push_back(goo[i]); // breaks here
}
}
So what are some causes of this strange behavior without a debugger attached and not under debug configuration? I've checked to make sure all of my variables are initialized, so I'm stumped. If you want to view the code above, the first part can be located here, and the second part here. Please forgive anything you see as "bad", and if you have suggestions that you just can't contain, then please do message me on GitHub.
Edit:
I looked more into it, and found out exactly what's causing the problem, but don't know how to fix it. This is the function where my app crashes (on OS X):
vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
{
vector<Drive *> Return;
if (HardDisks)
{
vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks();
for (int i = 0; i < (int)Disks.size(); i++)
{
DISK_DRIVE_INFORMATION ddi = Disks.at(i);
// First, try reading the disk way
Streams::xDeviceStream* DS = NULL;
try
{
char path[0x200] = {0};
wcstombs(path, ddi.Path, wcslen(ddi.Path));
DS = new Streams::xDeviceStream(ddi.Path);
}
catch (xException& e)
{
continue;
}
if (DS == NULL || DS->Length() == 0 || DS->Length() < HddOffsets::Data)
{
// Disk is not of valid length
continue;
}
DS->SetPosition(HddOffsets::Data);
// Read the FATX partition magic
int Magic = DS->ReadInt32();
// Close the stream
DS->Close();
// Compare the magic we read to the *actual* FATX magic
if (Magic == FatxMagic)
{
Drive *d = new Drive(Disks.at(i).Path, Disks.at(i).FriendlyName, false);
Return.push_back(d);
}
}
}
vector<Drive *> LogicalDisks = GetLogicalPartitions();
for (int i = 0; i < (int)LogicalDisks.size(); i++)
{
Return.push_back(LogicalDisks.at(i));
}
return Return;
}
If I change if (HardDisks) to if (HardDisks = false), the app works just fine. So, I looked into that scope and discovered that after vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks();, the heap gets corrupt or something like that. I noticed this because in the debugger, after that function is called, my HardDisks bool changes to "false", which wasn't what it was before.
Here is GetPhysicalDisks:
vector<Drive::DISK_DRIVE_INFORMATION> Drive::GetPhysicalDisks( void )
{
// RIGHT AFTER this vector is initialized, everything goes to hell
vector<Drive::DISK_DRIVE_INFORMATION> ReturnVector;
DIR *dir;
dirent *ent;
dir = opendir("/dev/");
if (dir != NULL)
{
// Read the shit
while ((ent = readdir(dir)) != NULL)
{
// Check the directory name, and if it starts with "disk" then keep it!
QRegExp exp("disk*");
exp.setPatternSyntax(QRegExp::Wildcard);
exp.setCaseSensitivity(Qt::CaseInsensitive);
if (exp.exactMatch(ent->d_name))
{
DISK_DRIVE_INFORMATION curdir;
memset(curdir.FriendlyName, 0, sizeof(curdir.FriendlyName));
memset(curdir.Path, 0, sizeof(curdir.Path));
char diskPath[0x50] = {0};
sprintf(diskPath, "/dev/r%s", ent->d_name);
mbstowcs(curdir.Path, diskPath, strlen(diskPath));
int device;
if ((device = open(diskPath, O_RDONLY)) > 0)
{
#ifdef __linux
hd_driveid hd;
if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
{
swprintf(curdir.FriendlyName, strlen(hd) * 2, L"%hs", hd.model);
}
#elif defined __APPLE__
mbstowcs(curdir.FriendlyName, ent->d_name, strlen(ent->d_name));
#endif
ReturnVector.push_back(curdir);
}
}
}
}
return ReturnVector;
}
While this isn't a real answer as to what happened, I did find a way to fix the problem. Looking at my edit above, I edited my Drive::GetFATXDrives function like so:
vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
{
// Initialize Disks vector up here
vector<DISK_DRIVE_INFORMATION> Disks;
// Call the function to get the hard disks
if (HardDisks)
Drive::GetPhysicalDisks(Disks);
vector<Drive *> ReturnVector;
if (HardDisks)
{
Streams::xDeviceStream* DS = NULL;
for (int i = 0; i < (int)Disks.size(); i++)
{
/* ... */
}
if (DS)
{
DS->Close();
delete DS;
}
}
vector<Drive *> LogicalDisks = GetLogicalPartitions();
for (int i = 0; i < LogicalDisks.size(); i++)
{
ReturnVector.push_back(LogicalDisks[i]);
}
return ReturnVector;
}
And my Drive::GetPhysicalDisks function now takes a vector<DISK_DRIVE_INFORMATION> reference instead of returning one. Seemed to make my program work just fine after that.