LINUX.ORG.RU

Проблемы с динамической памятью в C


0

0

Создаю в программе элемент бинарного дерева - структуру, содержащую числовое значение, указатель на строку и указатели на родителя и сыновей. Элемент создаётся в отдельной функции new_node, в которую передаются указатель на структуру, строковое значение и число. В new_node вызываю malloc для самой структуры и для строки, копирую содержимое аргумента строки в член структуры, и обнуляю указатели на соседние узлы дерева. Для отладки создал функцию, которыя выводит адрес структуры, значения строки и число, а также адреса соседних узлов. Создал один узел. Так вот в чем проблема: если вызвать функцию отладки в самом конце new_node, она - как и надо - выведет следующее:

0x804a008 node:1 (nil):(nil):(nil)

Но если ее вызывать сразу ПОСЛЕ вызова new_node, то происходит вот это:

0x80487a0 Segmentation fault

т.е. адрес структуры ПОМЕНЯЛСЯ. Как такое может быть?

anonymous

>вызываю malloc для самой структуры и для строки, копирую содержимое аргумента строки в член структуры

Тут нужно копать. Либо слишком мало выделяете для строки, Либо какая нибудь маленькая неточность.

Сег фолт говорит о том что неправильная работа с памятью.

fura13 ★★★
()

Действительно знаение адреса структуры меняется только в теле функции, переделал ее с возвратом нового адреса указателя и теперь все работает.

anonymous
()
Ответ на: комментарий от JavaHarlal

>Потренируйся лучше на кошках

Не лучше на яве.

x86 ★★
()
Ответ на: комментарий от JavaHarlal

>Знаешь, тебе рановато ещё программировать на Си. Потренируйся лучше на кошках.

Человек выдал связное и литературно приемлемое изложение алгоритма. Это говорит об интеллектуальных способностях, значительно превышающих среднеЛОРовские. Кроме того, ему хватило даже намека на то, где нужно искать проблему.

Так что потенции у него большие. Были бы кошки ;)

anonymous
()

> new_node, в которую передаются указатель на структуру,
передавай указатель на указатель на структуру.

omerm
()

Скорее всего Вы в функцию new_node()
передали указатель на структуру и выделили память
в этойже функции:
new_node_bad_bad(struct l * p_list)
{
  p_list = malloc(sizeof(struct l));
  ...
}

а нужно
new_node(struct l ** p_list)
{
  *p_list = (struct l *)malloc(sizeof(struct l));
  (*p_list)->name = (char *)malloc(sizeof(char)*100);
  strcpy((*p_list)->name, "123456_qwer");
}

Обычная ошибка связанная с выделением памяти в С.

Дело в том, что параметр функции не важно какой
копируется в стек этой функции, в данном случае
скопирован адрес на ячейку памяти.
Но при выделении памяти значение указателя
меняется на тот, который возвращает malloc(),
поэтому Вам нужно в стек функции скопировать
указатель на указатель нужной ячейки памяти,
а в самой функции разъименовать указатель
и присвоить ему значение возвращаемое malloc().

передовать в функцию new_node(struct l ** p_list)
соответственно нужно адрес указателя.

...
 struct l * p_l;
 new_node(&p_l);
 printf("name: %s \n", p_l->name); 
 free(p_l->name);
 free(p_l); 
...

Но это плохой стиль, лучше выделять память
в том-же блоке в котором и удаляется.
А иначе могут быть утечки памяти.
Но в С часто именно так и делают или
делают две функции: 
alloc_node()
delete_node()

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.