С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/34: Рейтинг темы: голосов - 34, средняя оценка - 4.65
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11

Освобождение памяти malloc free

29.03.2013, 22:02. Показов 6925. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В общем работаю над расширением для php (для тренировки в php и в c++ сразу) Суть дела вот в чем, наткнулся на конвертер php массива в массив c++ , суть вот в чем, функция ест память! Я не умею обращаться с ф-й malloc и free и по этомц ситуация поставила меня в тупик.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
void *php_array_to_c_array(zval *param,int type,int size,int *array_size)
{
  HashTable *param_ht = param->value.ht;
  zval **cur;
  void *params;
  void *array;
  int i,tmp_size = zend_hash_num_elements(param_ht);
  int id;
  zend_hash_internal_pointer_reset(param_ht);
  params = (void *)malloc(size * tmp_size);
  i = 0;
  while(zend_hash_get_current_data(param_ht,(void **)&cur) == SUCCESS)
    {
       if((*cur)->type == IS_ARRAY)
          {
              int new_array_size;
              void *array = php_array_to_c_array(*cur,type,size,&new_array_size);
              array = php_array_to_c_array(*cur,type,size,&new_array_size);
              params = realloc(params, (tmp_size + new_array_size) * size);
              memcpy(&((char*)params)[i*size],array,new_array_size * size);
              i += (new_array_size - 1);
              free(array);
          }
       else
          {
              switch(type)
                   {
                        case TO_C_FLOAT:
                            convert_to_double(*cur);
                            ((float*)params)[i] = (float)Z_DVAL_P(*cur);
                        break;
                        case TO_C_DOUBLE:
                            convert_to_double(*cur);
                            ((double*)params)[i] = Z_DVAL_P(*cur);
                        break;
                        case TO_C_INT:
                            convert_to_long(*cur);
                            ((int*)params)[i] = (int)Z_LVAL_P(*cur);
                        break;
                        case TO_C_LONG:
                            convert_to_long(*cur);
                            ((long*)params)[i] = Z_LVAL_P(*cur);
                        break;
                        case TO_C_UCHAR:
                        case TO_C_UBYTE: // yoya
                            convert_to_long(*cur);
                            ((unsigned char*)params)[i] = (unsigned char)Z_LVAL_P(*cur);
                        break;
                        case TO_C_SCHAR:
                            convert_to_long(*cur);
                            ((signed char*)params)[i] = (signed char)Z_LVAL_P(*cur);
                        break;
                        case TO_C_USHORT:
                            convert_to_long(*cur);
                            ((unsigned short*)params)[i] = (unsigned short)Z_LVAL_P(*cur);
                        break;
                        case TO_C_SHORT:
                            convert_to_long(*cur);
                            ((short*)params)[i] = (short)Z_LVAL_P(*cur);
                        break;
                        case TO_C_UINT:
                            convert_to_long(*cur);
                            ((unsigned int*)params)[i] = (unsigned int)Z_LVAL_P(*cur);
                        break;
                        case TO_C_STRING:
                            convert_to_string(*cur);
                            ((char **)params)[i] = estrdup(Z_STRVAL_P(*cur));
                        break;
                   }
          }
       zend_hash_move_forward(param_ht);
       i++;
    }
  if(array_size != NULL)
  *array_size = i;
  return (void *)params;
}
в общем я понял что нужно что-то сделать с переменное params, т.к. память выделяется, но не освобождается. Так что хелп если это возможно))
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.03.2013, 22:02
Ответы с готовыми решениями:

Из malloc-free в new delete
Есть код с выделением памяти с помощью malloc, надо сделать с new delete Вроде сделал, освобождение памяти работает, а с выделением...

SIGABRT после free malloc
не могу почистить string array matches (2 dim) проблема возникает на линии 114 отмеченной как //Cleaning up an array не могу почистить...

Управление памятью с использованием malloc и free
int n=3; int * v = (int*) malloc(n*sizeof(int)); // обьявил вектор из 3-х целочисельных елементов v = 0; v = 1; v =...

16
0 / 0 / 0
Регистрация: 29.03.2013
Сообщений: 18
29.03.2013, 23:20
C++
1
2
3
return (void *)params;
free(params);
}
насколько я знаю так
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
29.03.2013, 23:28
Systemes, когда функция malloc выделила память, то она вернула указатель на ее начало. Вы не должны его потерять. Когда вы перестаете нуждаться в этой памяти, то ее нужно освободить. Для это в функцию free передаем тот самый указатель, который мы запомнили. Груба говоря на каждый вызов malloc/calloc должен приходится вызов free.
Цитата Сообщение от Beg Посмотреть сообщение
насколько я знаю так
нет, все, что находится после оператора return не выполнится.
1
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
29.03.2013, 23:49  [ТС]
Цитата Сообщение от go Посмотреть сообщение
Systemes, когда функция malloc выделила память, то она вернула указатель на ее начало. Вы не должны его потерять. Когда вы перестаете нуждаться в этой памяти, то ее нужно освободить. Для это в функцию free передаем тот самый указатель, который мы запомнили. Груба говоря на каждый вызов malloc/calloc должен приходится вызов free.
Это я понимаю)) Вычитал из документации)) Тут чуть другое. Нужно и вернуть указатель params, и во free его передать, иначе память будет выделяться, но не будет освобождаться, т.е. получаю утечку. Вот мне и не понятно каким образом можно устранить утечку и не потерять данные params в данном случае...
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
29.03.2013, 23:57
"и вернуть и засунуть во free" - задача никак не решается.
можно конечно освободить память и вернуть указатель на нее, но пользоваться ей нельзя будет.
схема простая:
тот кто вызывает функцию php_array_to_c_array получает от нее указатель на память и он отвечает за вызов какой-то функции, которая приведет у удалению выделенной памяти. если он это сделать не в состоянии - то задачка не решается.
1
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
30.03.2013, 00:02
Systemes, а. Понял. Вариантов масса.
1. Создать класс. И освобождать память в деструкторе.
2. Возложить обязанность на освобождение памяти на подпрограмму, которая вызывает вашу функцию php_array_to_c_array.
0
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
30.03.2013, 00:11  [ТС]
Да есть указатель)) Я не подумал что через указатель можно освободить память, по этому не копал в эту сторону(( Но даже в этом случае что-то постепенно съедает память
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
typedef struct _efree_node_t {
  void *ptr;
  struct _efree_node_t *next;
} efree_node_t;
 
typedef struct _efree_list_t {
  efree_node_t *head, *tail;
} efree_list_t;
 
efree_list_t efree_list_on_flush_t;
 
void add_efree_list_on_flush(void *ptr) {  // сюда params отправляется из php_array_to_c_array
  efree_node_t *node = (efree_node_t *)malloc(sizeof(efree_node_t));
  node->ptr = ptr;
  node->next = NULL;
  if (efree_list_on_flush_t.head == NULL) {
    efree_list_on_flush_t.head = node;
    efree_list_on_flush_t.tail = node;
  } else {
    efree_list_on_flush_t.tail->next = node;
    efree_list_on_flush_t.tail = node;
  }
}
void free_efree_list_on_flush() {  // тут освобождается память
  efree_node_t *node, *next;
  node = efree_list_on_flush_t.head;
  while (node) {
    next = node->next;
    free(node->ptr);
    node = next;
  }
  efree_list_on_flush_t.head = NULL;
  efree_list_on_flush_t.tail = NULL;
}
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.03.2013, 00:11
Цитата Сообщение от Systemes Посмотреть сообщение
суть вот в чем, функция ест память!
Суть не в этом. Память в функции выделилась, копия указателя на неё вернулась из функции. Нужно дальше в коде смотреть, что происходит с этим указателем. Если значение его не сохранить, то будет утечка (указатель локальный). Когда эта память перестанет быть нужной, или перед очередным вызовом функции, нужно эту память освободить. Ещё вариант: объявить этот указатель глобально, в начале функции проверять, есть ли под ним память, если есть освобождать, и только потом выделять новую.
1
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
30.03.2013, 14:34  [ТС]
Ну в общем я понял куда копать)

Добавлено через 14 часов 13 минут
мне так и не удалось решить проблему с утечкой памяти
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
typedef struct _efree_node_t {
  void *ptr;
  struct _efree_node_t *next;
} efree_node_t;
 
typedef struct _efree_list_t {
  efree_node_t *head, *tail;
} efree_list_t;
 
efree_list_t efree_list_on_flush_t;
 
void add_efree_list_on_flush(void *ptr) {  // сюда params отправляется из php_array_to_c_array
  efree_node_t *node = (efree_node_t *)malloc(sizeof(efree_node_t));
  node->ptr = ptr;
  node->next = NULL;
  if (efree_list_on_flush_t.head == NULL) {
    efree_list_on_flush_t.head = node;
    efree_list_on_flush_t.tail = node;
  } else {
    efree_list_on_flush_t.tail->next = node;
    efree_list_on_flush_t.tail = node;
  }
}
void free_efree_list_on_flush() {  // тут освобождается память
  efree_node_t *node, *next;
  node = efree_list_on_flush_t.head;
  while (node) {
    next = node->next;
    free(node->ptr);
    node = next;
  }
  efree_list_on_flush_t.head = NULL;
  efree_list_on_flush_t.tail = NULL;
}
если меняю

C++
1
2
3
void add_efree_list_on_flush(void *ptr) {  // сюда params отправляется из php_array_to_c_array
  free(ptr);
}
утечка исчезает, следовательно проблема в функции free_efree_list_on_flush которая отвечает за освобождение памяти. В общем я реально запутался(
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.03.2013, 17:49
Утечка памяти - это когда указатели на выделенную память теряются. У вас может этого и нет. Может просто большой расход памяти, но это другое. Если я правильно понимаю, у вас связанный список, и на каждый узел выделяется память, а освобождение памяти происхоит, когда список удаляется. Это не утечка, код такой. Как с этим бороться и можно ли, нужно подумать...
0
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
30.03.2013, 20:24  [ТС]
Да вы правильно поняли))И к сожалению пока не могу найти ответа как справиться с данной проблемой...
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.03.2013, 22:18
Цель кода в чём?

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

Добавлено через 1 минуту
Памяти расходуется больше, чем размер массива?
0
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
31.03.2013, 11:33  [ТС]
Память расходуется в зависимости от размера поступившего массива. Причем чем больше массив, тем меньше расходуется памяти. Но есть порог, при котором память снова начинает расходоваться.

Память расходуется постепенно. При 65 вызовах ф-ии в сек-у где-то 0.22 мб в секунду, при учете что в массиве передается один парамет равный 0.

По идее к add_efree_list_on_flush будет обращается сразу несколько разных ф-й, и потом идет очищение памяти:

add_efree_list_on_flush
add_efree_list_on_flush
add_efree_list_on_flush

free_efree_list_on_flush

структура будет такая...
Ссылка на массив поступая в add_efree_list_on_flush отправляется еще и в основную ф-ю.
free_efree_list_on_flush вызывается когда с массивами произойдут все операции
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
31.03.2013, 14:12
Интересно, а какое это отношение тема имеет к С++? Чистый С же. Применимо к ++ следовало бы использовать какой-нибудь из smart-pointer'ов.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
31.03.2013, 20:52
???
Цитата Сообщение от alsav22 Посмотреть сообщение
Цель кода в чём?
Цитата Сообщение от alsav22 Посмотреть сообщение
Памяти не хватает при работе программы?
Добавлено через 6 минут
Чтобы попытаться разобраться с расходом памяти, того кода, который вы показали, недостаточно.
0
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
31.03.2013, 21:46  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//-- объявление констант
void *php_array_to_c_array(zval *param,int type,int size,int *array_size);
#define php_array_to_string_array(z) (char **)php_array_to_c_array(z,TO_C_STRING,sizeof(char *),NULL)
#define php_array_to_byte_array(z) (char *)php_array_to_c_array(z,TO_C_BYTE,sizeof(char),NULL)
#define php_array_to_ubyte_array(z) (unsigned char*)php_array_to_c_array(z,TO_C_UBYTE,sizeof(unsigned char),NULL)
#define php_array_to_long_array(z) (long *)php_array_to_c_array(z,TO_C_LONG,sizeof(long),NULL)
#define php_array_to_double_array(z) (double *)php_array_to_c_array(z,TO_C_DOUBLE,sizeof(double),NULL)
#define php_array_to_int_array(z) (int *)php_array_to_c_array(z,TO_C_INT,sizeof(int),NULL)
#define php_array_to_float_array(z) (float *)php_array_to_c_array(z,TO_C_FLOAT,sizeof(float),NULL)
#define php_array_to_uchar_array(z) (unsigned char *)php_array_to_c_array(z,TO_C_UCHAR,sizeof(unsigned char),NULL)
#define php_array_to_schar_array(z) (signed char *)php_array_to_c_array(z,TO_C_SCHAR,sizeof(signed char),NULL)
#define php_array_to_ushort_array(z) (unsigned short *)php_array_to_c_array(z,TO_C_USHORT,sizeof(unsigned short),NULL)
#define php_array_to_short_array(z) (short *)php_array_to_c_array(z,TO_C_SHORT,sizeof(short),NULL)
#define php_array_to_uint_array(z) (unsigned int *)php_array_to_c_array(z,TO_C_UINT,sizeof(unsigned int),NULL)
 
// -- объявление zend функции pointer
ZEND_FUNCTION(pointer)
{
zval *type, *pointer;
void *v_pointer = NULL;
TWO_PARAM(type, pointer);
convert_to_array(pointer);
switch(Z_LVAL_P(type))
{
case T_SHORT:
v_pointer = php_array_to_short_array(pointer);
break;
case T_INT:
v_pointer = php_array_to_int_array(pointer);
break;
case T_FLOAT:
v_pointer = php_array_to_float_array(pointer);
break;
case T_DOUBLE:
v_pointer = php_array_to_double_array(pointer);
break;
}
Pointer((int)Z_LVAL_P(type),(void*)v_pointer);
add_efree_list_on_flush(v_pointer);
}
 
//-- ф-я обработки
ZEND_FUNCTION(flush)
{
ZERO_PARAM();
Flush();
free_efree_list_on_flush();
}
Это оставшийся код, который участвует во всей схеме. Но основные ф-ии pointer и flush память точно не расхдуют. Т.к. закоментировав эти ф-ии получаю ту же "утечку", или передавая массив написанный в ручную, без ф-ии конвертации (т.е. не используя php_array_to_c_array и free_efree_list_on_flush) память не расходуется)
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
31.03.2013, 22:14
И как это проверять?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.03.2013, 22:14
Помогаю со студенческими работами здесь

Работа с памятью через malloc,realloc и free
Вот начал работать с памятью в c++ и появилось несколько вопросов. 1 - r = (int *)malloc((1)*sizeof(int)); как я понимаю, эта запись...

И снова динамическая память, malloc и free в конструкторе и деструкторе
Короче есть, класс, который например хранит строку, я его храню в структуре, после я выдиляю динамическу память пот эту структуру и копирую...

Резервирование памяти/освобождение памяти для трехмерного массива
Необходимо создать трехмерный массив (A), в котором элементы вдоль направления Z выли бы выровнены по 16 байт. Есть две проблемы: ...

В чем преимущества new и delete и могут ли они действительно заменить функции calloc, malloc, free, realloc?
Язык программирования C поддерживает функции динамического управления пямятью: calloc, malloc, free, realloc - которые неподдерживают...

Выделение памяти malloc
не работает пример из лекции , там пример на доске такой написан - #include <stdlib.h> int main() { int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru