2015-11-04 3 views
1

У меня есть небольшая программа, в которой у меня есть две структуры: Person - Состоит из id и основных методов Ppl - Состоит из массива людей с некоторыми методами для работы с массивом.C++ - Массив структурных указателей

struct Person { 
const int id; 
Person(); 
Person(int a); 
}; 

Person::Person(int a) : id(a) {} 

Это структура Person с ее методами.

const int MAX = 5; 

Устанавливает ограничение на длину массива

struct Ppl { 
static int current; //Keeps track of current position in array 
Person *ppls[MAX]; //Creates an array of Person structure pointers 
void add(int a);  //Adds a person with id to the next available position 
//void remove(int b); 
int searchid(int c); //Searches ppls for an id c. 
Ppl();    //Constructor 
}; 

int Ppl::current = 0; //Initializing static variable 

void Ppl::add(int a) { 
int ret = searchid(a);   //Determine if id a already exists in ppls 
//cout << "Ret: " << ret << endl; 
if (ret > MAX) {    //If value returned is > MAX, value exists 
    cout << "User " << a << " already exists" << endl; 
} else {      //else, add it to the next available spot 
    Person p(a); 
    ppls[current] = &p; 
    cout << "Added user: " << a << " at index: " << current << endl; 
    current++; 
} 
} 

Ppl::Ppl() { 
current = 0; 
int i = 0; 
while (i < MAX) { //Sets all Person pointers to NULL on initialization 
    ppls[i] = NULL; 
    cout << "ppls[" << i << "] is NULL" << endl; 
    i++; 
} 
} 

int Ppl::searchid(int c) { 
int i = 0; 
bool found = false; 
while(i < MAX) { 
    if (ppls[i] == NULL) { //If NULL, then c wasn't found in array because 
    break;     //there is no NULL between available spots. 
    } else { 
    if (ppls[i]->id == c) { 
    found = true; 
    } 
    } 
    i++; 
} 
if (found == true) { 
    return 10;  //A number higher than MAX 
} else { 
    return 1;  //A number lower than MAX 
} 
} 

Основная функция:

int main() { 
Ppl people; 
people.add(21); 
cout << people.ppls[0]->id << endl; 
people.add(7); 
cout << people.ppls[0]->id << " "; 
cout << people.ppls[1]->id << endl; 
people.add(42); 
cout << people.ppls[0]->id << " "; 
cout << people.ppls[1]->id << " "; 
cout << people.ppls[2]->id << endl; 
people.add(21); 
cout << people.ppls[0]->id << " "; 
cout << people.ppls[1]->id << " "; 
cout << people.ppls[2]->id << " "; 
cout << people.ppls[3]->id << endl; 
} 

Вывод, который я получаю:

ppls[0] is NULL 
ppls[1] is NULL 
ppls[2] is NULL 
ppls[3] is NULL 
ppls[4] is NULL 
Added user: 21 at index: 0 
21 
Added user: 7 at index: 1 
7 0 
Added user: 42 at index: 2 
42 0 0 
Added user: 21 at index: 3 
21 0 0 0 

Почему добавлять все новые записи в начале rray, сохраняя остальное NULL? Почему он не обнаружил, что 21 уже был добавлен.

Я сошел с ума, пытаясь понять это. Любая помощь приветствуется. Большое спасибо сообществу.

EDIT Я исправил его так, что он добавляет элементы в массив и распознает, существует ли идентификатор.

Я внес изменения в структуры Ppl путем добавления деструктор:

Ppl::~Ppl() { 
int i = 0; 
while (i < MAX) { 
    delete ppls[i]; 
    i++; 
} 
} 

и путем изменения способа добавления.

void Ppl::add(int a) { 
int ret = searchid(a); 
//cout << "Ret: " << ret << endl; 
if (ret > MAX) { 
    cout << "User " << a << " already exists" << endl; 
} else { 
    **Person *p = new Person(a); 
    ppls[current] = p;** 
    cout << "Added user: " << a << " at index: " << current << endl; 
    current++; 
} 
} 

Так выход теперь

ppls[0] is NULL 
ppls[1] is NULL 
ppls[2] is NULL 
ppls[3] is NULL 
ppls[4] is NULL 
Added user: 21 at index: 0 
21 
Added user: 7 at index: 1 
21 7 
Added user: 42 at index: 2 
21 7 42 
User 21 already exists 
Segmentation fault (core dumped) 

Что ошибку сегментации и как я могу это исправить? Еще раз спасибо

+0

Вы» переназначение адреса переменной стека в массив указателей ... Всегда плохая идея.'Person p (a);' then 'ppls [current] = & p;'? У меня нет времени, чтобы написать правильный ответ, но у вас есть длинный путь в карьере программирования ... – nonsensickle

+0

Спасибо. И я знаю. Я все еще только студент –

+0

Извините, если я сошел с ума или оскорбления. Приятно видеть, что новые люди занимаются программированием, жаль, что у меня не было времени, чтобы помочь должным образом. Добро пожаловать в клуб! – nonsensickle

ответ

4
Person p(a); 
ppls[current] = &p; 

есть проблема. Вы сохраняете указатель на локальную переменную. Ваша программа подвержена неопределенному поведению.

Использование

Person* p = new Person(a); 
ppls[current] = p; 

Убедитесь, чтобы удалить объекты в деструктор Ppl.

Предложение по улучшению

Пока не ясно, что ваша цель с помощью этой программы, но вы можете сделать вашу жизнь намного проще с помощью

std::vector<Person> ppls; 

вместо

Person *ppls[MAX]; 
+0

Спасибо за помощь. Причина, по которой я не могу использовать векторы, и причина, по которой у этой программы нет четкой цели, заключается в том, что я написал эту программу, чтобы понять некоторые понятия, с которыми я столкнулся. Нас учили использовать структуры в моей школе, и я пробовал упражнение. –

+0

Я запустил программу после исправления ошибок. Я получаю ошибку сегментации. См. Мое редактирование выше. –

+0

@thisisalongdisplayname, ошибка сегментации вызвана последней строкой в ​​'main', так как' people.ppls [3] 'is' NULL'. –

Смежные вопросы