|
Динамический массив структур, Создание / удаление |
|
|
|
May 5 2009, 09:25
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
К примеру у меня есть структура и я хочу работать с динамическим массивом, правильно ли будет: Код typedef struct { DWORD Debug; char *Oerr; char Oerr_num; WORD Data_FC; char Nfunc; } SProba; ... int num = 3; SProba *dat = (SProba*) malloc(sizeof(SProba) * num); SProba *elem = &dat[1]; elem->Oerr = (char*) malloc(10); .... for(i = 0; i < num; i++) free(dat[i]->Oerr; free(dat);
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
May 5 2009, 11:15
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
Oldring, описалась. Понятно, что скобку не закрыла. А по существу, всё таки не ясно. Забыла сказать, пишу в Cross Studio 1.7.13 для LPC2214
Сообщение отредактировал YChebisheva - May 5 2009, 11:16
|
|
|
|
|
May 5 2009, 12:05
|

Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142

|
Простите, а разве нельзя? Типа было под него выделено ни сколько памяти, и освободиться ни сколько.... Если это неправильно, то уже есть в структуре размер массива Oerr: Oerr_num. Освобождая проверять его... Код for(i = 0; i < num; i++) { if ( dat[i]->Oerr_num > 0 ) { free(dat[i]->Oerr); } } free(dat); Но это непринципиально, интересно, почему нельзя освобождать память если её не выделяли.
|
|
|
|
|
May 5 2009, 12:28
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Злодей @ May 5 2009, 15:05)  интересно, почему нельзя освобождать память если её не выделяли. Наверное, потому, что при выделении памяти её (память) никто не обнуляет, и там - некий мусор, который может быть воспринят как "правильные" данные, и таки память будет "освобождена" (о чем менеджер кучи будет уведомен; к этой памяти "пришиты" указатели на другие участки кучи, которые (указатели) будут изменены; при этом, по-видимуму, испортятся некие нужные Вам данные (уж куча разрушится точно!) и т.д.)... P.S. Прочитал что написал - сумбурно получилось... Другими словами: при освобождении памяти с помощью free менеджер кучи не имеет возможности проверить - точно ли выделялся этот участок памяти или программист ошибся; и, скорее всего, его "освободит" с непредсказуемыми последствиями.
|
|
|
|
|
May 5 2009, 13:14
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Злодей @ May 5 2009, 15:05)  Простите, а разве нельзя? Типа было под него выделено ни сколько памяти, и освободиться ни сколько.... Нельзя. Вам не было "выделено нисколько памяти" - вам память не выделялась вообще. В free() нужно передавать указатель на то же место, который вернул вам malloc(). Дело в том, что перед выделенным вам участком менеджер памяти хранит служебную информацию об этом участке. Когда вы вызываете free(), менеджер использует эту информацию для возврашения освобожденной памяти в кучу и объединения ее с другими свободными участками. Если вы вызовете free() с каким-то другим адресом - совершенно случайная информация перед этим указателем разрушит данные менеджера кучи. Единственное исключение - допускается вызов free с указателем равным 0, в таком случае он просто ничего не делает. У вас в примере память выделяется только для одного элемента из трех. Поэтому вы должны либо выделить память и для остальных, либо обнулить остальные указатели.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 5 2009, 13:22
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(YChebisheva @ May 5 2009, 12:25)  К примеру у меня есть структура и я хочу работать с динамическим массивом, правильно ли будет: правильно так: Код int num = 3; SProba *dat = (SProba*) calloc(num,sizeof(SProba)); for(i = 0; i < num; i++) free(dat[i]->Oerr; free(dat); но только в случае, если NULL == 0
|
|
|
|
|
May 5 2009, 14:02
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
Ребята это я виновата, Вас всех запутала. Понятно, что в примере выделено меньше, чем освобождается, и надо делать проверку на нул. Меня интересесовал другой вопрос. Создание массива должно проходить так: Код int num = 3; SProba *dat = (SProba*) malloc(sizeof(SProba) * num); Обращение к элементу можно или так делать: Код SProba *elem = &dat[1]; elem->Debug = 123; //или так: dat[1].Debug = 123; А освобождение: Код free(dat) А по части Oerr я просто хотела спросить, что разницы не будет, что я динамически выделяю память на структуру, в которой есть указатель на другую переменную, под которую я также выделю память. И соотвественно, если я в SProba, к примеру у dat[0], выделила память под Oerr, я ее должна в конце и освободить free(dat[0]->Oerr), а потом уже освободить free(dat). Ну а где не юзаю Oerr, просто у остальных элементов Oerr = NULL...
|
|
|
|
|
May 6 2009, 06:31
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
Как понимаю особой разницы malloc и calloc нет, просто во втором случае весь массив обнуляется, плюс в первом случае указываешь общий объем: размер элемента * кол.элемента, а в calloc - просто раздельно это сделано. А удаление одинаково - через free(dat)?
Сообщение отредактировал YChebisheva - May 6 2009, 06:40
|
|
|
|
|
May 6 2009, 08:28
|
Участник

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070

|
у меня ещё вопрос возник по части объема, которая занимает структура. Есть, к примеру, структура: Код typedef struct { long *Debug; char Nfunc; } SGfuncBAK; Показывает, что 8 байт, 4 понятно на указатель, а куда ещё 4, а не 1? или там выравнивание?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|