我是新编程和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();
}
答案 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 memory用std::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
个对象被引用。