1. ホーム
  2. c++

[解決済み] exc_bad_access エラー

2022-02-15 11:26:33

質問内容

宿題でプログラムを書いています。 プログラムはコンパイルして実行されますが、不正なアクセスエラーが発生します。

これは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

哺乳類.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";
}

犬.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

犬.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";
}

他の派生クラス(馬、豚、猫)はすべてDogと同じです。 ListAnimals()がGetWeight()に到達するとExc_Bad_Accessエラーが発生するのですが、どうしたらいいでしょうか? 私が知る限り、それは正しいファイルタイプを返しています。 どんなヘルプでも素晴らしいです。

解決方法は?

あなたの MammalAssignment 関数は、ローカル変数へのポインタを返しています。 関数が戻ると、そのメモリ(スタック上にあったもの)は消えてしまい、該当するmammal型のオブジェクトとしてアクセスするとクラッシュします。

で確保したメモリへのポインタを返す必要があります。 operator new に適切なコピーセマンティックスが実装されていれば、ポインタの代わりにオブジェクトを使うこともできます。 Mammal クラスがあります。

これ以上進む前に、C++のメモリ管理について復習(または最初の自己学習? 以下も参照してください。 スマートポインタ を回避するために new/delete 可能な限り、あなたの生活を楽にするために。