關於free釋放內存

最近將C程序設計教程(C How To Program)第二版

書上12-3的例子敲上電腦

程序如下:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>


struct listNode {
 char data;
 struct listNode * nextPtr;
};

typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;

void insert (LISTNODEPTR *, char);
char deletex (LISTNODEPTR *, char);
int isEmpty (LISTNODEPTR);
void printList (LISTNODEPTR);
void instructions (void);

int main ()
{
 LISTNODEPTR startPtr = NULL;
 int choice;
 char item;
 
 instructions ();
 printf ("?");
 scanf ("%d", &choice);
 
 while (choice != 3)
 {
  
  switch (choice)
  {
  case 1:
   printf ("Enter a character:");
   scanf ("/n%c", &item);
   insert (&startPtr, item);
   printList (startPtr);
   break;
  case 2:
   if (! isEmpty (startPtr))
   {
    printf ("Enter character to be deleted:");
    scanf ("/n%c", &item);
    
    if (deletex (&startPtr, item))
    {
     printf ("%c deleted. /n", item);
     printList (startPtr);
    }
    else
     printf ("%c not found. /n /n", item);
   }
   else
    printf ("List is empty./n/n");
   
   break;
   
  default:
   printf ("Invalid choice. /n /n");
   instructions ();
   break;
   
  }
  
  printf ("?");
  scanf ("%d", &choice);
 }
 
 printf ("End of run. /n");
 return 0;
}


void instructions (void)
{
 printf ("Enter your choice: /n"
  "1 to insert an element into the list. /n"
  "2 to delete an element from the list. /n"
  "3 to end. /n");
}

void insert (LISTNODEPTR *sPtr, char value)
{
 LISTNODEPTR newPtr, previousPtr, currentPtr;
 //newPtr = (LISTNODEPTR)malloc (sizeof (LISTNODE));

   newPtr = malloc (sizeof (LISTNODEPTR));
 
 if (newPtr != NULL)
 {
  newPtr->data = value;
  newPtr->nextPtr = NULL;
  
  previousPtr = NULL;
  currentPtr = *sPtr;
  
  while (currentPtr != NULL && value > currentPtr->data)
  {
   previousPtr = currentPtr;
   currentPtr = currentPtr->nextPtr;
  }
  
  if (previousPtr == NULL)
  {
   newPtr->nextPtr = *sPtr;
   *sPtr = newPtr;
  }
  else
  {
   previousPtr->nextPtr = newPtr;
   newPtr->nextPtr = currentPtr;
  }
 }
 else
  printf ("%c not inserted. No memory available. /n", value);
}


char deletex (LISTNODEPTR *sPtr, char value)
{
 LISTNODEPTR previousPtr, currentPtr, tempPtr;
 
 if (value == (*sPtr)->data)
 {
  tempPtr = *sPtr;
  *sPtr = (*sPtr)->nextPtr;
  free (tempPtr);
  return value;
 }
 else
 {
  previousPtr = *sPtr;
  currentPtr = (*sPtr)->nextPtr;
  
  while (currentPtr != NULL && value != currentPtr->data)
  {
   previousPtr = currentPtr;
   currentPtr = currentPtr->nextPtr;
  }
  
  if (currentPtr != NULL)
  {
   tempPtr = currentPtr;
   previousPtr->nextPtr = currentPtr->nextPtr;
   free (tempPtr);
   return value;
  }
 }
 
 return '/0';
}

int isEmpty (LISTNODEPTR sPtr)
{
 return sPtr == NULL;
}

void printList (LISTNODEPTR currentPtr)
{
 if (currentPtr == NULL)
  printf ("List is empty. /n/n");
 else
 {
  printf ("The list is: /n");
  
  while (currentPtr != NULL)
  {
   printf ("%c-->", currentPtr->data);
   currentPtr = currentPtr->nextPtr;
  }
  
  printf ("NULL /n/n");
 }
}

 

在運行插入的時候沒問題

不過刪除的時候就出問題了

調試發現時運行的free(tempPtr);出問題的

最後發現是書上打錯了

就是申請結點空間的那句:

newPtr = malloc (sizeof (LISTNODEPTR));
應該改爲:

newPtr = (LISTNODEPTR)malloc (sizeof (LISTNODE));

申請的應該是結構體的空間

而不是指向結構體的指針的空間

本人水平有限,一時沒看出來
糾結了老半天

改了之後就沒問題了

最後再說下

因爲碰到釋放內存錯誤

所以我也查了下

free只能釋放堆內存

不能釋放棧內存

其實堆棧我也不大理解

不過暫時理解是這樣子

堆內存是使用malloc動態分配的內存空間

棧內存就是使用int等這些關鍵字申請的空間

運行圖片如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章