将对象添加到数组时EXC_BAD_ACCESS

时间:2018-09-05 16:26:11

标签: c++ class

我是新编程和C ++。我试图使用数组创建Roster个对象的Person,然后在Roster中打印People的属性。

当我尝试将人添加到personArray时,我得到

Exception = EXC_BAD_ACCESS (code=1, address=0x0).

我认为这与我的personArray的范围有关,但我似乎无法弄清楚。

这是我正在使用的代码:

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

class Person 
{
public:
    Person(string name, int age);
    string getName() {
        return name;
    }
    void setName(string n) {
        name = n;
    }
    int getAge() {
        return age;
    }
    void setAge(int a) {
        age = a;
    }
private:
    string name;
    int age;
};

class Roster {
public:
    void addToPersonArray(string name, string age) {
        Person person(name, stoi(age));
        personArray[personCount] = &person;
    }
    void printPersonArray() {
        for (int i = 0; i < 5; i++)
            cout << personArray[i]->getName() << '\t' << personArray[i]->getAge() << '\n';
    }
private:
    Person *personArray[5];
    int personCount = 0;
};

int main() {
    const string studentData[] = {"Dan,45", "Mark,33", "Mary,22", 
"April,17", "Jill,22"};
    Roster roster;

    stringstream ss(studentData[0]); // just testing the first entry
    vector<string> result;

    while (ss.good()) {
        string substr;
        getline(ss, substr, ',');
        result.push_back(substr);
    }
    roster.printPersonArray();
}

2 个答案:

答案 0 :(得分:1)

问题在这里:

void addToPersonArray(string name, string age) {
    Person person(name, stoi(age));
    personArray[personCount] = &person;
}

person是成员函数addToPersonArray()中的局部变量,在函数作用域之后将被销毁。

因此,存储局部变量的地址(并尝试在printPersonArray()中访问它)只会给您undefined behavior

很幸运您的程序遇到了异常。


还有一点要注意的是,您实际上并没有使用roster来测试程序。相反,您要做的只是解析并保存到result向量。您可以在while循环之后添加它,以使其真正起作用。

if (result.size() == 2) {
     roster.addToPersonArray(result[0], result[1]);
}

建议:由于您使用固定的数组大小,因此您可能想用reserving the memorystd::array<Person, 5>std::vector<Person>用5 {{1} },位于Person的中。

查看示例输出:https://wandbox.org/permlink/tAGqqnhCfwz1wPrH

Roster

输出:

#include <iostream>
#include <sstream>
#include <vector>
#include <array>

class Person {
public:
    Person(const std::string& name, int age): name(name), age(age) {}
    std::string getName()const { return name;   }
    void setName(const std::string& n){ name = n;   }
    int getAge()const     { return age;     }
    void setAge(int a)    { age = a;    }
private:
    std::string name;
    int age;
};

class Roster {
public:
    Roster() { personArray.reserve(5); } // reserve some memory
    void addToPersonArray(const std::string& name, const std::string& age) {
        personArray.emplace_back(name, stoi(age));
    }
    void printPersonArray() {
        // use range loop, which will assure, access what you have.
        for (const Person& person: personArray)
            std::cout << person.getName() << '\t' << person.getAge() << '\n';
    }
private:
    std::vector<Person> personArray;
    //int personCount = 0; --------------> no need anymore
};

int main() {
    std::array<std::string,5> studentData{ "Dan,45", "Mark,33", "Mary,22", "April,17", "Jill,22" };
    Roster roster;
    for(const std::string& str: studentData)
    {
        std::stringstream ss(str);
        std::vector<std::string> result;    
        while (ss.good()) {
            std::string substr;
            std::getline(ss, substr, ',');
            result.emplace_back(substr);
        }
        if (result.size() == 2) {
            roster.addToPersonArray(result
                [0], result[1]);
        }
    }
    roster.printPersonArray();
    return 0;
}

答案 1 :(得分:1)

除了在addToPersonArray()函数中存储指向局部变量的指针之外,main()函数也不向personArray添加任何条目。

相反,main创建一个Roster对象,并在使用一些不受Roster影响的代码之后,直接进入调用roster.printPersonArray,这样做:

void printPersonArray() 
{
    for (int i = 0; i < 5; i++)  // <-- This will loop for all 5 entries
        cout << personArray[i]->getName() << '\t' << personArray[i]->getAge() << '\n';
}

由于personArray从未初始化为包含指向Person对象的有效指针,因此该循环将导致未定义的行为。

问题是您有一个personCount成员变量,但无法利用它来控制数组中有多少个有效条目。该循环应如下编写:

void printPersonArray() 
{
    for (int i = 0; i < personCount; i++)  
        cout << personArray[i]->getName() << '\t' << personArray[i]->getAge() << '\n';
}

除了存储指向局部变量的指针外,您的Roster::addToPersonArray()不会检查personCount是否大于4,因此这是代码中您无法使用{{ 1}},以控制有多少personCount个对象被引用。