реклама на сайте
подробности

 
 
> Динамический массив структур, Создание / удаление
YChebisheva
сообщение May 5 2009, 09:25
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 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);
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
Oldring
сообщение May 5 2009, 09:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



Цитата(YChebisheva @ May 5 2009, 13:25) *
free(dat[i]->Oerr;


Нет.


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение May 5 2009, 11:15
Сообщение #3


Участник
*

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



Oldring, описалась. Понятно, что скобку не закрыла.
А по существу, всё таки не ясно.
Забыла сказать, пишу в Cross Studio 1.7.13 для LPC2214

Сообщение отредактировал YChebisheva - May 5 2009, 11:16
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 5 2009, 11:46
Сообщение #4


Гуру
******

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



Цитата(YChebisheva @ May 5 2009, 14:15) *
А по существу, всё таки не ясно.
Так, по существу - и неправильно! Что выделялось по malloc, то и должно быть освобождено c помощью free...

P.S. В Вашем примере кода Вы выделяете два участка памяти, а освобождаете - четыре...
Go to the top of the page
 
+Quote Post
Злодей
сообщение May 5 2009, 12:05
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 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);


Но это непринципиально, интересно, почему нельзя освобождать память если её не выделяли.
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 5 2009, 12:28
Сообщение #6


Гуру
******

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



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

P.S. Прочитал что написал - сумбурно получилось... Другими словами: при освобождении памяти с помощью free менеджер кучи не имеет возможности проверить - точно ли выделялся этот участок памяти или программист ошибся; и, скорее всего, его "освободит" с непредсказуемыми последствиями.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 5 2009, 13:14
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 5 2009, 13:22
Сообщение #8


;
******

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 5 2009, 13:31
Сообщение #9


Гуру
******

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



Цитата(_Pasha @ May 5 2009, 16:22) *
но только в случае, если NULL == 0
Разве malloc/calloc обнуляет выделенный участок памяти?
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение May 5 2009, 14:02
Сообщение #10


Участник
*

Группа: Новичок
Сообщений: 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...
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 5 2009, 14:17
Сообщение #11


Гуру
******

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



Цитата(YChebisheva @ May 5 2009, 17:02) *
Меня интересесовал другой вопрос.
Всё - верно. Для массива "красивее" использовать calloc. И маленькая ошибка в коде, нужно free(dat[i].Oerr), а не free(dat[i]->Oerr)

P.S. Повторюсь: В выделенной памяти - мусор. Не забудьте очистить (проинициализировать) Ваш массив - занести нули или "пустые"("безопасные") значения.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 5 2009, 15:07
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Палыч @ May 5 2009, 16:31) *
Разве malloc/calloc обнуляет выделенный участок памяти?
calloc обязан обнулить
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение May 6 2009, 06:31
Сообщение #13


Участник
*

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



Как понимаю особой разницы malloc и calloc нет, просто во втором случае весь массив обнуляется, плюс в первом случае указываешь общий объем: размер элемента * кол.элемента, а в calloc - просто раздельно это сделано.
А удаление одинаково - через free(dat)?

Сообщение отредактировал YChebisheva - May 6 2009, 06:40
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 6 2009, 06:35
Сообщение #14


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(YChebisheva @ May 6 2009, 09:31) *

Совершенно ага.
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение May 6 2009, 08:28
Сообщение #15


Участник
*

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



у меня ещё вопрос возник по части объема, которая занимает структура.
Есть, к примеру, структура:
Код
typedef struct {              
                long   *Debug;
                char    Nfunc;
               } SGfuncBAK;

Показывает, что 8 байт, 4 понятно на указатель, а куда ещё 4, а не 1? или там выравнивание?
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 00:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.0147 секунд с 7
ELECTRONIX ©2004-2016