После компиляции VS2008 падает после удаления узла дерева, имеющего потомка - C (СИ)
Формулировка задачи:
Вот код на Си:
программа строит дерево, печатает его, удаляет узлы (с удалением всех дочерних узлов).
в борладне все работает. Под *nix системами после компиляции gcc и в win после компиляции VS2008 падает после удаления узла дерева, имеющего потомка. Не могу разобраться почему, вроде все корректно выделяю, да и free передаю тот же адрес, что выделил мне malloc. Помогите разобраться, пожалуйста.
Выделю место, где программа падает, на всякий:
Листинг программы
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- #include <conio.h>
- struct Node;
- struct ChildNode{
- struct ChildNode *prev;
- struct ChildNode *next;
- struct Node *element;
- };
- typedef struct ChildNode childnode;
- struct Node{
- int index;
- double value;
- childnode *parent;
- childnode *children;
- };
- typedef struct Node node;
- struct List{
- int count;
- struct List *prev;
- };
- typedef struct List list;
- node *first;
- int count = 0;
- node *GetElementByIndex(int index, node *t)
- {
- node *temp = NULL;
- childnode *c;
- if (t==NULL)
- return NULL;
- if (t->index==index)
- return t;
- c=t->children->next;
- if (c==NULL)
- return NULL;
- while (c!=NULL)
- {
- temp=GetElementByIndex(index,c->element);
- if (temp!=NULL)
- break;
- c=c->next;
- }
- if (temp!=NULL)
- return temp;
- return NULL;
- }
- int AddNode(int index, double value)
- {
- node *t, *temp;
- childnode *c, *child;
- if (first==NULL)
- {
- temp = (node *)malloc(sizeof(node));
- temp->value = value;
- temp->index = 1;
- temp->children = (childnode*)malloc(sizeof(childnode));
- temp->children->prev = NULL;
- temp->children->next = NULL;
- temp->children->element = NULL;
- first=temp;
- count=1;
- return 0;
- }
- t = GetElementByIndex(index,first);
- if (t==NULL)
- return -1;
- ++count;
- temp = (node *)malloc(sizeof(node));
- child = (childnode*)malloc(sizeof(child));
- temp->value = value;
- temp->index = count;
- temp->parent = child;
- temp->children = (childnode*)malloc(sizeof(childnode));
- temp->children->prev = NULL;
- temp->children->next = NULL;
- temp->children->element = NULL;
- child->next = NULL;
- child->element = temp;
- c=t->children;
- while (c->next!=NULL)
- c=c->next;
- child->prev = c;
- c->next = child;
- return 0;
- }
- void PrintTree(const char *str, node *p)
- {
- childnode *c;
- char temp[50];
- if (p==NULL)
- return;
- printf("%s%i: %0.2f\n",str,p->index,p->value);
- if (p->children->next==NULL)
- return;
- strcpy(temp,str);
- strcat(temp,"\t\0");
- c=p->children->next;
- while (c!=NULL)
- {
- PrintTree(temp,c->element);
- c=c->next;
- }
- return;
- }
- void DeleteTree(node *p)
- {
- childnode *c, *cTemp;
- c=p->children->next;
- while (c!=NULL)
- {
- DeleteTree(c->element);
- cTemp = c;
- c = c->next;
- free(cTemp); //Падает тут
- cTemp = NULL;
- }
- free(p->children);
- if (first==p)
- first = NULL;
- else
- {
- if (p->parent->next!=NULL)
- p->parent->next->prev = p->parent->prev;
- p->parent->prev->next = p->parent->next;
- }
- p->parent->element=NULL;
- free(p);
- }
- void Delete(int index)
- {
- node *t;
- if (first==NULL)
- return;
- t = GetElementByIndex(index,first);
- if (t==NULL)
- return;
- DeleteTree(t);
- return;
- }
- int main()
- {
- char c;
- int index, cnt;
- double value;
- do
- {
- c = getch();
- switch(c)
- {
- case '1':
- PrintTree("", first); break;
- case '2':
- printf("Input index and value to input: "); scanf("%i%le",&index,&value); AddNode(index,value); break;
- case '3':
- printf("Input index to delete"); scanf("%i",&index); Delete(index); break;
- }
- } while (c!='4');
- }
Листинг программы
- c=p->children->next;
- while (c!=NULL)
- {
- DeleteTree(c->element);
- cTemp = c;
- c = c->next;
- free(cTemp); //Падает тут
- cTemp = NULL;
- }
Решение задачи: «После компиляции VS2008 падает после удаления узла дерева, имеющего потомка»
textual
Листинг программы
- p = malloc (....);
- printf ("malloc res=%p\n", p);
- printf ("res[-1]=0x%08x\n", *(((int*)p)-1));
- printf ("res[-2]=0x%08x\n", *(((int*)p)-2));
Объяснение кода листинга программы
p = malloc (....);
- здесь происходит выделение памяти динамическим способом при помощи функцииmalloc
. В точке вызова функцииmalloc
передается некий аргумент, который определяет размер выделяемой памяти. Точный размер памяти не указан в вопросе, поэтому в описании кода этот аргумент не приводится.printf (
malloc res=%p\n, p);
- здесь выполняется вывод информации о выделенной памяти. Форматированный вывод осуществляется при помощи функцииprintf
. Передается строка форматаmalloc res=%p
и указатель на выделенную памятьp
. Результатом выполнения этого фрагмента кода будет строка, в которой будет указано место выделения памяти.printf (
res[-1]=0x%08x\n, *(((int*)p)-1));
- здесь выполняется доступ к значению, находящемуся по адресуp - 1
, который интерпретируется как целое число. Поскольку указательp
указывает на начало блока памяти, то выражениеp - 1
будет указывать на последний элемент этого блока. Затем происходит форматированный вывод значения этого элемента при помощи функцииprintf
. В данном случае выводится значение без знака разыменования, что означает, что адрес интерпретируется как смещение от начала блока памяти.printf (
res[-2]=0x%08x\n, *(((int*)p)-2));
- здесь выполняется доступ к значению, находящемуся по адресуp - 2
, который интерпретируется как целое число. Затем происходит форматированный вывод значения этого элемента при помощи функцииprintf
. В данном случае выводится значение без знака разыменования, что означает, что адрес интерпретируется как смещение от начала блока памяти.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д