简体   繁体   中英

exc_bad_access error

I'm writing a program for a homework assignment. The program compiles and runs, but has a bad access error.

This is main.cpp

#include <iostream>
#include <string>
#include "Mammal.h"
#include "Dog.h"
#include "Horse.h"
#include "Pig.h"
#include "Cat.h"

using namespace std;
//Seed for ease of grading
const int SEED=100;
const int NUM_ANIMALS=5;
const int WEIGHT_LIMIT=150;


void MammalAssignment(const Mammal * new_Mammal, int choice, string newName);
void UserChoice(const Mammal * new_Mammal);
void ListAnimal(const Mammal *new_Mammal);


int main()
{
    string newName, newWeight;

    srand(SEED);
    Mammal *new_Mammal[NUM_ANIMALS];

    UserChoice(*new_Mammal);
    for(int i=0; i<NUM_ANIMALS; i++)
        ListAnimal(new_Mammal[i]);



    //Program pauses for user input to continue
    char exit_char; 
    cout<<"\nPress any key and <enter> to exit\n";
    cin>>exit_char;

    return 0;
}

void UserChoice(const Mammal * new_Mammal)
{
    int choice;
    bool choiceGood;
    string newName;

    for(int i=0;i<NUM_ANIMALS; i++){
        choiceGood=false;
        while(choiceGood==false)
        {   
            cout<<"-Please choose a number 1-4 for the corresponding animal-\n"
                <<"1-Dog\n2-Horse\n3-Pig\n4-Cat\n";

            cin>>choice;  //User choice

            if(choice<=0 || choice >=5){
                cout<<"Your choice is invalid\n\n";
                continue;
            }

            choiceGood=true;
        } //While loop
        cout<<"\nPlease enter a name for the animal you have chosen(Ex. Fido).\n";
        cin>>newName;

        MammalAssignment(&new_Mammal[i], choice, newName);
    }  //For loop

}

void MammalAssignment(const Mammal * new_Mammal, int choice, string newName)
{
    if(choice==1){
        Dog newDog(rand()%(WEIGHT_LIMIT+1), newName);
        new_Mammal=&newDog;
    }
    else if(choice==2){
        Horse newHorse(rand()%(WEIGHT_LIMIT+1), newName);
        new_Mammal=&newHorse;
    }
    else if(choice==3){
        Pig newPig(rand()%(WEIGHT_LIMIT+1), newName);
        new_Mammal=&newPig;
    }
    else if(choice==4){
        Cat newCat(rand()%(WEIGHT_LIMIT+1), newName);
        new_Mammal=&newCat;
    }
}

void ListAnimal(const Mammal *new_Mammal)
{
    cout<<"-------------------------\nName:"
        <<new_Mammal->GetName()<<"\nWeight: "
        <<new_Mammal->GetWeight();
}

Mammal.h

#ifndef MAMMAL_H
#define MAMMAL_H

using namespace std;

class Mammal
{
public:
    Mammal(); //Default constructor

    Mammal( int newWeight);  //Parameterized constructor

    void SetWeight(int newWeight);

    virtual string GetName() const;

    int GetWeight() const;
    //virtual function to be  defined by derived animal classes
    virtual void Speak() const;
private:
    int weight;

};

#endif

Mammal.cpp

#include <iostream>
#include <string>
#include "Mammal.h"

using namespace std;

Mammal::Mammal()
{
    SetWeight(0);
    cout<<"\nInvoking default Mammal Constructor\n";
}

Mammal::Mammal( int newWeight)
{
    SetWeight(newWeight);
    cout<<"\nInvoking parameterized Mammal Constructor\n";
}

void Mammal::SetWeight(int newWeight)
{
    weight=newWeight;
}

int Mammal::GetWeight() const
{
    return weight;
}

string Mammal::GetName() const
{}

void Mammal::Speak() const
{
    cout<<"\nLadies and gentlemen, the mammal speaks...\n";
}

Dog.h

#ifndef DOG_H
#define DOG_H

#include "Mammal.h"

using namespace std;

class Dog: public Mammal
{
public:
    Dog(); //Default constructor

    Dog(const int& newWeight,const string& newName);  //Parameterized constructor

    void SetName(string newName);

    string GetName() const;
    //mammal virtual function 
    virtual void Speak() const;

private:
    string name;
};

#endif

Dog.cpp

#include <iostream>
#include <string>
#include "Dog.h"

using namespace std;
//Default constructor
Dog::Dog()
{
    cout<<"\nInvoking default Dog constructor\n";
}
//Parameterized constructor
Dog::Dog( const int& newWeight,const string& newName):Mammal(newWeight)  
{
    SetName(newName);
    cout<<"\nInvoking parameterized Dog constructor.\n";
}

void Dog::SetName(string newName)
{
    name=newName;
}

string Dog::GetName() const
{
    return name;
}
//mammal virtual function 
void Dog::Speak() const
{
    Mammal::Speak();
    cout<<"\nWoof!\n";
}

The other derived classes(horse, pig, and cat) are all identical to Dog. I'm getting a Exc_Bad_Access error when ListAnimals() gets to GetWeight(). As far as I can tell it's returning the right file type. Any help would be awesome

Your MammalAssignment function is returning a pointer to a local variable. Once the function returns, that memory (which was on the stack) is gone and you will crash when you access it as an object of the relevant mammal type.

You need to return a pointer to memory allocated using operator new , or possibly just an object instead of a pointer, assuming suitable copy semantics are implemented in your Mammal classes.

A revision (or initial self-education?)of memory management in C++ would be in order before you go any further. See also smart pointers , to avoid new/delete where possible and make your life easier.

Mammal *new_Mammal[NUM_ANIMALS];

You need to allocate memory using new !

Mammal *new_Mammal = new Mammal[NUM_ANIMALS];

Also I think your UserChoice function should take the pointer as a reference and not as a const value to be able to change the actual content.

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