简体   繁体   中英

Crashing when objects are deleted

It's crashing at the very end of the main() function where it needs to delete the starters objects. The error message that pops up when I run the program says: Debug assertion failed! Expression: _BLOCK_IS_VALID(pHead->nBlockUse). How do i fix it from crashing when deleting the starters objects?

#include <iostream>
#include <fstream>
#include "olympic.h"

using namespace std;

ofstream csis;

int main() {
const int lanes = 4;
Ranker rank(lanes);

csis.open("csis.txt");

// First make a list of names and lane assignments.
Competitor* starters[lanes];

starters[0] = new Competitor("EmmyLou Harris", 1);
starters[1] = new Competitor("Nanci Griffith", 2);
starters[2] = new Competitor("Bonnie Raitt", 3);
starters[3] = new Competitor("Joni Mitchell", 4);

// The race is run; now assign a time to each person.
starters[0]->setTime((float)12.0);
starters[1]->setTime((float)12.8);
starters[2]->setTime((float)11.0);
starters[3]->setTime((float)10.3);

// Put everyone into the ranker.
for (int i = 0; i < lanes; i++)
    rank.addList(starters[i]);

// Now print out the list to make sure its right.
cout << "Competitors by lane are:" << endl;
csis << "Competitors by lane are:" << endl;
for (int i = 1; i <= lanes; i++)
    rank.getLane(i)->print();

// Finally, show how they finished.
cout << "Rankings by finish are:" << endl;
csis << "Rankings by finish are:" << endl;
for (int i = 1; i <= lanes; i++)
    rank.getFinish(i)->print();
for (int i = 0; i < lanes; i++)
    delete starters[i];

csis.close();

}

ranker.cpp:

#include "ranker.h"
#include "competitor.h"
#include <stdlib.h>

Ranker::Ranker(int lanes) {
athlete = new Competitor*[lanes]; 
numAthletes = 0;
maxAthletes = lanes;
}

int Ranker::addList(Competitor* starter) {
if (numAthletes < maxAthletes && starter != NULL) {
    athlete[numAthletes] = starter;
    numAthletes++;

    return numAthletes;
}
else
    return 0;
}

Competitor* Ranker::getLane(int lane) {
for (int i = 0; i < numAthletes; i++) {
    if (athlete[i]->getLane() == lane) {
        return athlete[i];
    }
}
return NULL;
}


Competitor* Ranker::getFinish(int position) {
switch(position) {
    case 1:
        return athlete[3];
        break;
    case 2:
        return athlete[2];
        break;
    case 3:
        return athlete[1];
        break;
    case 4:
        return athlete[0];
        break;
}
return NULL;
}

int Ranker::getFilled() {
return numAthletes;
}

Ranker::~Ranker() {
delete [] athlete;
}

competitor.h:

#ifndef _COMPETITOR_H
#define _COMPETITOR_H

 class Competitor {
     private:
        char* name;
        int lane;
        double time;
     public:
        Competitor(char* inputName, int inputLane);
        Competitor();
        void setTime(double inputTime);
        char* getName();
        int Competitor::getLane();
        double getTime();
        void print();
       ~Competitor();
    };

    #endif

competitor.cpp:

#include "competitor.h"
#include <string>
#include <iostream>
#include <iomanip>

using namespace std;


 Competitor::Competitor(char* inputName, int inputLane) {
name = inputName;
lane = inputLane;
}

Competitor::Competitor() {
name = 0;
lane = 0;
time = 0;
}

 void Competitor::setTime(double inputTime) {
time = inputTime;
}

char* Competitor::getName() {
return name;
}

int Competitor::getLane() {
return lane;
 }

 double Competitor::getTime() {
return time;
}

void Competitor::print() {
cout << setw(20) << name << setw(20) << lane << setw(20) << setprecision(4) << time        << endl;
}

Competitor::~Competitor() {
delete [] name;
}

Call stack:

before crash: http://i.imgur.com/d4sKbKV.png after crash: http://i.imgur.com/C5cXth9.png

After you've added Competitor class, it seems the problem is that you delete its name in Competitor's destructor. But you assign it from string literal which can't really be deleted. I'm sure the stack trace leading to assertion will prove that.

One way of solving the problem would be using std::string to store the name.

Problem is when deleting the char* value on destructor, which is assigned with const char instead new char. So i have slightly changed the constructor to copy the const char to new char.

Competitor::Competitor(char* inputName, int charlen, int inputLane) 
{
name = new char[charlen + 1];
memcpy(name , inputName, charlen );
name [charlen] = '\0'; 
lane = inputLane;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM