После компиляции VS2008 падает после удаления узла дерева, имеющего потомка - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Вот код на Си:
#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');
}
программа строит дерево, печатает его, удаляет узлы (с удалением всех дочерних узлов). в борладне все работает. Под *nix системами после компиляции gcc и в win после компиляции VS2008 падает после удаления узла дерева, имеющего потомка. Не могу разобраться почему, вроде все корректно выделяю, да и free передаю тот же адрес, что выделил мне malloc. Помогите разобраться, пожалуйста. Выделю место, где программа падает, на всякий:
  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));

Объяснение кода листинга программы

  1. p = malloc (....); - здесь происходит выделение памяти динамическим способом при помощи функции malloc. В точке вызова функции malloc передается некий аргумент, который определяет размер выделяемой памяти. Точный размер памяти не указан в вопросе, поэтому в описании кода этот аргумент не приводится.
  2. printf (malloc res=%p\n, p); - здесь выполняется вывод информации о выделенной памяти. Форматированный вывод осуществляется при помощи функции printf. Передается строка формата malloc res=%p и указатель на выделенную память p. Результатом выполнения этого фрагмента кода будет строка, в которой будет указано место выделения памяти.
  3. printf (res[-1]=0x%08x\n, *(((int*)p)-1)); - здесь выполняется доступ к значению, находящемуся по адресу p - 1, который интерпретируется как целое число. Поскольку указатель p указывает на начало блока памяти, то выражение p - 1 будет указывать на последний элемент этого блока. Затем происходит форматированный вывод значения этого элемента при помощи функции printf. В данном случае выводится значение без знака разыменования, что означает, что адрес интерпретируется как смещение от начала блока памяти.
  4. printf (res[-2]=0x%08x\n, *(((int*)p)-2)); - здесь выполняется доступ к значению, находящемуся по адресу p - 2, который интерпретируется как целое число. Затем происходит форматированный вывод значения этого элемента при помощи функции printf. В данном случае выводится значение без знака разыменования, что означает, что адрес интерпретируется как смещение от начала блока памяти.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5
Похожие ответы