Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.63
Systemes
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
29.03.2013, 22:02     Освобождение памяти malloc free #1
В общем работаю над расширением для 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, т.к. память выделяется, но не освобождается. Так что хелп если это возможно))
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.03.2013, 22:02     Освобождение памяти malloc free
Посмотрите здесь:

C++ Освобождение памяти
SIGABRT после free malloc C++
резервирование памяти/освобождение памяти для трехмерного массива C++
C++ Работа с памятью через malloc,realloc и free
выделение памяти malloc C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Beg
0 / 0 / 0
Регистрация: 29.03.2013
Сообщений: 17
29.03.2013, 23:20     Освобождение памяти malloc free #2
C++
1
2
3
return (void *)params;
free(params);
}
насколько я знаю так
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
29.03.2013, 23:28     Освобождение памяти malloc free #3
Systemes, когда функция malloc выделила память, то она вернула указатель на ее начало. Вы не должны его потерять. Когда вы перестаете нуждаться в этой памяти, то ее нужно освободить. Для это в функцию free передаем тот самый указатель, который мы запомнили. Груба говоря на каждый вызов malloc/calloc должен приходится вызов free.
Цитата Сообщение от Beg Посмотреть сообщение
насколько я знаю так
нет, все, что находится после оператора return не выполнится.
Systemes
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
29.03.2013, 23:49  [ТС]     Освобождение памяти malloc free #4
Цитата Сообщение от go Посмотреть сообщение
Systemes, когда функция malloc выделила память, то она вернула указатель на ее начало. Вы не должны его потерять. Когда вы перестаете нуждаться в этой памяти, то ее нужно освободить. Для это в функцию free передаем тот самый указатель, который мы запомнили. Груба говоря на каждый вызов malloc/calloc должен приходится вызов free.
Это я понимаю)) Вычитал из документации)) Тут чуть другое. Нужно и вернуть указатель params, и во free его передать, иначе память будет выделяться, но не будет освобождаться, т.е. получаю утечку. Вот мне и не понятно каким образом можно устранить утечку и не потерять данные params в данном случае...
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
29.03.2013, 23:57     Освобождение памяти malloc free #5
"и вернуть и засунуть во free" - задача никак не решается.
можно конечно освободить память и вернуть указатель на нее, но пользоваться ей нельзя будет.
схема простая:
тот кто вызывает функцию php_array_to_c_array получает от нее указатель на память и он отвечает за вызов какой-то функции, которая приведет у удалению выделенной памяти. если он это сделать не в состоянии - то задачка не решается.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
30.03.2013, 00:02     Освобождение памяти malloc free #6
Systemes, а. Понял. Вариантов масса.
1. Создать класс. И освобождать память в деструкторе.
2. Возложить обязанность на освобождение памяти на подпрограмму, которая вызывает вашу функцию php_array_to_c_array.
Systemes
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
30.03.2013, 00:11  [ТС]     Освобождение памяти malloc free #7
Да есть указатель)) Я не подумал что через указатель можно освободить память, по этому не копал в эту сторону(( Но даже в этом случае что-то постепенно съедает память
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;
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.03.2013, 00:11     Освобождение памяти malloc free #8
Цитата Сообщение от Systemes Посмотреть сообщение
суть вот в чем, функция ест память!
Суть не в этом. Память в функции выделилась, копия указателя на неё вернулась из функции. Нужно дальше в коде смотреть, что происходит с этим указателем. Если значение его не сохранить, то будет утечка (указатель локальный). Когда эта память перестанет быть нужной, или перед очередным вызовом функции, нужно эту память освободить. Ещё вариант: объявить этот указатель глобально, в начале функции проверять, есть ли под ним память, если есть освобождать, и только потом выделять новую.
Systemes
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
30.03.2013, 14:34  [ТС]     Освобождение памяти malloc free #9
Ну в общем я понял куда копать)

Добавлено через 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 которая отвечает за освобождение памяти. В общем я реально запутался(
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.03.2013, 17:49     Освобождение памяти malloc free #10
Утечка памяти - это когда указатели на выделенную память теряются. У вас может этого и нет. Может просто большой расход памяти, но это другое. Если я правильно понимаю, у вас связанный список, и на каждый узел выделяется память, а освобождение памяти происхоит, когда список удаляется. Это не утечка, код такой. Как с этим бороться и можно ли, нужно подумать...
Systemes
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
30.03.2013, 20:24  [ТС]     Освобождение памяти malloc free #11
Да вы правильно поняли))И к сожалению пока не могу найти ответа как справиться с данной проблемой...
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.03.2013, 22:18     Освобождение памяти malloc free #12
Цель кода в чём?

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

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

Память расходуется постепенно. При 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 вызывается когда с массивами произойдут все операции
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
31.03.2013, 14:12     Освобождение памяти malloc free #14
Интересно, а какое это отношение тема имеет к С++? Чистый С же. Применимо к ++ следовало бы использовать какой-нибудь из smart-pointer'ов.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
31.03.2013, 20:52     Освобождение памяти malloc free #15
???
Цитата Сообщение от alsav22 Посмотреть сообщение
Цель кода в чём?
Цитата Сообщение от alsav22 Посмотреть сообщение
Памяти не хватает при работе программы?
Добавлено через 6 минут
Чтобы попытаться разобраться с расходом памяти, того кода, который вы показали, недостаточно.
Systemes
0 / 0 / 0
Регистрация: 05.07.2012
Сообщений: 11
31.03.2013, 21:46  [ТС]     Освобождение памяти malloc free #16
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) память не расходуется)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.03.2013, 22:14     Освобождение памяти malloc free
Еще ссылки по теме:

C++ Освобождение памяти в C++
Освобождение памяти C++
И снова динамическая память, malloc и free в конструкторе и деструкторе C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
31.03.2013, 22:14     Освобождение памяти malloc free #17
И как это проверять?
Yandex
Объявления
31.03.2013, 22:14     Освобождение памяти malloc free
Ответ Создать тему
Опции темы

Текущее время: 06:52. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru