2010-12-03 4 views
3

Добрый день!Я использую malloc правильно?

мне нужно использовать таНос в создании системы список студент .... Для того, чтобы быть эффективным, наш профессор попросил нас использовать его на структуры, так что я создал на структуру следующим образом:

struct student { 
     char studentID[6]; 
     char name[31]; 
     char course [6]; 
}; 
struct student *array[30]; 

каждый раз, когда я добавляю запись, то есть когда я использую malloc ...

array[recordCtr]=(struct student*)malloc(sizeof(struct student)); 
recordCtr++; 

затем я освобождаю это следующим образом.

for(i = 0; i < recordCtr; i++){ 
     free(array[i]); 
    } 

Я использую malloc правильно ??? каков эффект, если я освобожу его, как это, вместо цикла выше.

free(array); 

Заранее спасибо. Ваше мнение будет высоко оценено.

ответ

4

У вас все в порядке.

free(array); будет определено поведение, потому что array сам не был выделен с помощью malloc поэтому вы не free его и может не нужно - память будет управляться компилятором.

1

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

Ваше текущее решение верное.

+0

Да. это глобальная переменная – newbie 2010-12-03 08:44:00

1

Что вы делаете правильно.

Вы можете придумать *array[30] как массив из 30 указателей Когда вы выделяете память для каждого из этих указателей, вам также необходимо вызвать free() для каждого из них.

1

Да, вы используете его правильно. Есть лучшие способы организовать хранилище, чем это, но это будет работать. По крайней мере, пока вам не понадобится более 30 студентов ...

Обратите внимание, что вы должны позвонить по номеру free() с каждым указателем, который возвращается malloc(). Это означает, что ваш цикл над массивом указателей является правильным подходом для выбранной вами архитектуры.

Ваша попытка позвонить бесплатно по массиву не будет работать. Он вызывает Undefined Behavior, потому что вы передаете указатель (на базу самого массива) до free(), который не вызван вызовом malloc().

1

Выглядит хорошо.

Вы можете (если это соответствует вашей проблеме) выделить пространство для всех 30 структур в один присест

struct student *array = (struct student *)malloc(30*sizeof(struct student)); 

whhen вы хотите избавиться от пространства, то вы можете сделать

free(array) 
1

Что вы будете работать отлично.Как уже упоминалось, вы создали массив указателей в стеке, и вам нужно malloc и освободить каждый из них по отдельности, как вы это делаете.

Однако, вы не должны использовать таНос и свободный один-структуру, в то время, вы можете сделать что-то вроде этого:

int arraySize = 30; 
student * ourArray = (student*)malloc(sizeof(student) * arraySize); 

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

Надеюсь, что это помогает.

1

инициализировать массив указатель на структуру студента с NULL значениями

for(i = 0; i < recordCtr; i++){ 
     array[i] = NULL; 
    } 

Свободная память, если массив [я] не NULL

for(i = 0; i < recordCtr; i++){ 
     if(NULL != array[i]) 
     { 
      free(array[i]); 
     } 
    } 
+0

Могу ли я узнать, зачем мне нужно инициализировать массив и установить его в NULL? Благодарю. – newbie 2010-12-03 09:00:13

+0

что будет, если я не сделаю ... – newbie 2010-12-03 09:00:31

+0

@newbie: Если вы не инициализируете массив указателей, они могут содержать значения мусора. Если вы попытаетесь освободить стоимость мусора, ваше время работы C имеет тенденцию разрушаться в куче дымящегося шлака. – JeremyP 2010-12-03 09:28:34

3

Хороший наконечник должен всегда делать:

type *something; 
something = malloc(n * sizeof(*something)); 

Это потому, что, если вы меняете тип чего-то, вам не нужно менять всевозможные другие коды. И sizeof - действительно операция компилятора здесь, она не будет превращаться во что-то другое во время выполнения.

Кроме того, не бросайте указатель void *, возвращаемый malloc, в C нет причин для этого, и это просто связывает ваш код вместе.

Так что в вашем случае не делать:

(struct student*)malloc(sizeof(struct student)); 

но

malloc(sizeof(**array)); 
2

Там нет ничего противозаконного о том, как вы используете таНос, но это не список, что это массив указателей.

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

Для назойливого списка вы ставите struct student * next в декларации студента. Для неинтрузивного списка вы создаете еще одну структуру student_list_node, которая содержит экземпляр struct student и указатель struct student_list_node * next;

Это exacmple из неинтрузивной версии:

struct student_list_node 
{ 
    struct student data; 
    struct student_list_node * next; 
}; 

struct student_list_node * head; 
struct student_list_node * tail; 

struct student_list_node * addStudentToTail() 
{ 
    struct student_list_node * newnode = (struct student_list_node *)(malloc(sizeof(struct student_list_node)); 
    /* check malloc did not fail or use a checking vesrion of malloc */ 
    if(!tail) 
    { 
     head = tail = newnode; 
    } 
    else 
    { 
     tail->next = newnode; 
     tail = newnode; 
    } 
    return newnode; // which is also "tail" 
} 

int main() 
{ 
    struct student_list_node * node = addStudentToTail(); 
    struct student * pstud = &node->data; 
    /* write to pstud student details */ 
} 

Если вы действительно хотите использовать массив, вы можете захотеть сделать это массив студента, а не студент * в этом случае вам можно использовать calloc вместо таНос

struct student * array = (struct student *)calloc(30, sizeof(student));

Затем с помощью free(array) бы правильный способ избавиться от него. У вас также есть возможность выделить больше, если вам это нужно позже с realloc. (Будьте осторожны с этим: вы должны сохранить копию исходного указателя, пока не узнаете, что realloc успешно).

1

Существует простое правило: каждый malloc() должен быть сопряжен с free() с указателем, возвращаемым malloc. Не меньше, не больше.

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