Освобождение памяти с помощью free () whoes указатель находится внутри указателя на структуру - PullRequest
1 голос
/ 18 ноября 2010

Эй! Я знаю, что название вопроса очень страшно, но я все еще не могу выразить проблему в одной строке!

Итак, я иду:

Существует указатель данных, скажем, DataPtr, который указывает на динамически распределенную память, и указатель другой структуры, скажем, StructPtr, который также указывает на динамически распределенную структуру.

И оба они находятся в другой структуре, скажем OuterStructure.

Существует связанный список, который содержит указатель на OuterStructure.

struct StructONE
{
  int a;
  char b;
  float c;
};

struct InnerStruct
{
  char a;
  int b;
};

struct StructTWO
{
   int Num;
   char * DataPtr;
   struct InnerStruct * StructPtr;  
};

struct LinkList
 {
   int NodeNum;
   int NodeType;       /* To Indicate Whether Pointer is of StructOne or StructTwo */  
   void * Ptr;        /* This can be of type StructONE or StructTWO */
   struct LinkList * Next;

 };

LinkList * Start;
void main()
{

  /* Structure Declarations */
    InnerStruct * InnerStructure;
    StructONE * OneStruct;
    StructTWO * TwoStruct;

 /* Fill up all the Structure */
     InnerStructure= (InnerStruct *)calloc(100,sizeof(InnerStruct));
     InnerStructure->a='a';
     InnerStructure->b=5;

  OneStruct= (StructONE *)calloc(100,sizeof(StructONE));
  TwoStruct= (StructTWO *)calloc(100,sizeof(StructTWO));

  TwoStruct->Dataptr=(char *) calloc(10,sizeof(char));
  TwoStruct->StructPtr= InnerStructure;



 /* Add these to Linked List
   void Add_to_Linked_List(int NodeNum,int NodeType,void *ptr)
 */
   Add_to_Linked_List(1,1,OneStruct);
   Add_to_Linked_List(2,2,TwoStruct);

/* Everything is Okey Till Here.
   Now When I want to delete a node from linked list,
   First I have to release Memory pointed by DataPtr and StructPtr. */

  DeleteNode(1);

} /* End of Main */

Код для DeleteNode выглядит следующим образом:

void DeleteNode(int Num)
{
  LinkList * NodePtr,*TempNode;
NodePtr= Start;

  while(NodePtr->NodeNum!=Num)
      NodePtr=NodePtr->Next;

  /* Now NodePtr points to desired node */
   if(NodePtr->NodeType==1) /* Pointer is StructONE Type */
     {
        free(NodePtr->Ptr);
        TempNode->Next=NodePtr->Next;
        free(NodePtr);
        return;
     }
    else
     {
        /* Now the Problem Begins.... 
           In StructTWO type, I have to release Memory allocated for DataPtr as well Struct Ptr */
        free((NodePtr->ptr)->DataPtr);   
/* This Line Generates Error as
  Error C2227: left of '->DataPtr' must point to class/struct/union/generic type    */


     }


}

Что мне делать ??

Я знаю, что ужасно написал код ... но должен написать это очень сложно !! (

Спасибо, что прочитали и это !!

Ответы [ 4 ]

4 голосов
/ 18 ноября 2010

#define STRUCT_ONE 1
#define STRUCT_TWO 2

struct LinkList
 {
   int NodeNum;
   int NodeType;
   union 
    {
      StructONE * Ptr_One;
      StructTWO * Ptr_Two;
    };

 };

................

   if(NodePtr->NodeType==STRUCT_ONE)
     {
        free(NodePtr->Ptr_One);
        TempNode->Next=NodePtr->Next;
        free(NodePtr);
        return;
     }
    else
     {
        free(NodePtr->Ptr_Two->DataPtr);   
        ....
     }

3 голосов
/ 18 ноября 2010
free((NodePtr->ptr)->DataPtr);   

Прежде всего, это правда, что ваш код ужасен. Во-вторых, у вас нет члена ptr. У вас есть Ptr участник. И последний void *, поэтому, если вы хотите получить DataPtr из него, вы должны использовать приведение

free(((struct StructTwo*)(NodePtr->Ptr))->DataPtr);   
1 голос
/ 18 ноября 2010

Нужно привести к правильному типу

/* I like parenthesis :-) */
((struct StructTwo *)(NodePtr->ptr))->DataPtr
0 голосов
/ 18 ноября 2010

Вам нужно разыграть:

if(NodePtr->NodeType==1) /* Pointer is StructONE Type */
 {
      ....
 }
else
 {
     struct StructTwo * s2ptr;
     s2ptr = (struct StructTwo *)NodePtr->ptr;
     free(s2ptr->DataPtr);
     free(s2ptr->StructPtr);
     free(NodePtr);
  }

Если вы используете указатель более одного раза, объявляя переменную для удержания, вы избегаете приведения типов в каждой строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...