2014-10-27 4 views
1

У меня есть следующие структуры, как, например:Как назначить массив указателю в структуре?

#define MAX_PEOPLE 16 
typedef struct { 
    int age; 
}Person; 

typedef struct { 
    Person *people; 
    int numPeople; 
}Team; 

Я пытаюсь выделить массив лиц в функции, передаются параметрами. Мой Team должен хранить массив из 16 указателей Person. Я не могу понять, что я делаю неправильно.

void initiateTeam(Team * team){ 
    team->numPeople = MAX_PEOPLE; 
    Person *p[MAX_PEOPLE]; 
    for(int i=0; i<MAX_PEOPLE;i++){ 
    p[i] = malloc(sizeof(Person); 
    } 
    team->people = &p[0]; 
} 

Я распечатал адреса моего team->people[i], и я получаю случайный мусор. Почему оценка team->people = &p[0] не так? Не следует ли получить первый адрес моего массива, затем выполнить арифметику указателя?

+1

Для чего вам нужно изменить свой malloc как sizeOf (Person) – LeatherFace

+0

Как вы используете этот массив? Вы выделили место для указателей, а не структур –

+0

О да! Понимаю, почему для массива нам нужен размер, который у людей не размер, указатель – lzc

ответ

1

Поскольку в комментариях вы заявили, что вы пытаетесь выделить массив Person объектов и не указателей, вам лучше сделать:

void addPeople(Team * team){ 
    team->numPeople = MAX_PEOPLE; 
    team->people = malloc(sizeof(Person) * MAX_PEOPLE); 
} 

ум, что нет в sizeof нет * поскольку вы не 't требуется массив указателей, но объектов. Позже вы сможете получить доступ к отдельным элементам (т.е. каждый Person объектов) с

team->people[2].age = 25; // The third person in the array 

Наконец, помните, чтобы освободить память.

1

Вы указываете team->people на статически определенный массив указателей на человека. Как только функция заканчивается, указатель стека возвращается к тому месту, где оставлено основное, стирая всю ранее локальную память в функции addPeople. Вам нужно malloc p и вернуть его из функции

+0

массив ('p') находится в стеке, а не« статически ». – Javier

+0

@Javier Я имею в виду статичный, как в постоянном размере, а не ключевое слово static. – LeatherFace

+0

фраза «статически определенный массив» имеет определенное значение, и это не для массивов в стеке, постоянного размера или нет. – Javier

1

Ваша переменная p выделена в стеке функции addPeople(). Назначение team->people = &p[0] (что эквивалентно team->people = p) является действительным, но опасным, поскольку этот адрес будет недействительным, как только функция будет завершена.

Лучше создать p с помощью malloc(sizeof (Person *) * MAX_PEOPLE) вместо использования стека.

+0

' p' - это массив указателей на 'Person' – Javier

1

Проблема здесь:

Person *p[MAX_PEOPLE]; 

Выделяет локальную переменную в функции держать массив указателей людей.

Вы получаете адрес этой локальной переменной и отправляете ее обратно. Как только вы не находитесь в функции, локальные данные освобождаются. Это было просто выделено на местном уровне. Это уже недействительно. Я мог бы работать некоторое время, или это может быть не в зависимости от того, что программа делает дальше.

Вы хотите:

Person **p = (Person **)malloc(sizeof (Person *) * MAX_PEOPLE); 
1

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

Кроме того, я думаю, что вам не нужен массив указателей для людей, а массив людей. Ваша структура является правильным, но я бы реализовать свою функцию так:

void addPeople(Team * team){ 
    team->numPeople = MAX_PEOPLE; 
    team->people = malloc(sizeof(Person) * MAX_PEOPLE); 
} 

И не забудьте free() ваш team->people.

Но если MAX_PEOPLE является предварительным определением процессора, то совершенно бесполезно использовать память из кучи. Если вы не храните слишком много людей в своей структуре, стек может легко выполнить ваши требования.

+0

Предположим, если я выделяю всю полноту памяти' people', как я могу получить доступ к второму, третьему лицу в моих 'people' когда это не массив. – lzc

+0

Вы можете использовать оператор [] в переменной 'Person * people;'. Просто убедитесь, что указатель указывает на достаточно большое пространство памяти и что вы не получаете доступ к памяти за пределами ее границ. – ruabmbua