링크드리스트에서 노드추가는 잘되는데 , 모든 노드를 삭제하는 부분에서 세그멘테이션 오류가 뜹니다;

jindongp의 이미지

아래부분은 링크드리스트 함수들이 모여있는 부분입니다.
gcc에서 컴파일하고 있었고요,,

그런데 , 링크드리스트로 메모리에 올리고 나서 , 노드들의 내용 출력은 잘되는데,
마지막에 , 프로그램 종료하기전에 KillAllBookNode(); 함수를 호출하여
모든 노드들을 지워주려하면 "세그멘테이션 오류" 가 뜹니다;;

일단 링크드리스트 부분에 무슨 잘못이 있지는 않는지 좀 봐주시면 감사하겠습니다 ㅎ;
고수님들의 많은 지적 부탁드립니다

#include "linkedbook.h"

// 링크드리스트에 새로운 노드를 추가하기 위한 함수.
void AddBookNode ( BOOKNODE *pHead , BOOKNODE node )
{
BOOKNODE *pFind;
BOOKNODE *pNew;

// 새로운 노드를 동적할당.
pNew = (BOOKNODE *) malloc ( sizeof(BOOKNODE) );

// 동적할당된 노드에 인자로 받은 노드의 데이터를 대입.
*pNew = node;

// 탐색을 위한 포인터를 head에 위치한다.
pFind = pHead;

// next가 NULL일 때까지 계속 다음 노드를 따라간다.
while ( pFind->next != NULL )
{
pFind = pFind->next;
}

// pFind가 맨 마지막 노드를 가리키게 되면 ,
// pFind의 다음노드가 새롭게 할당된 노드를 가리키게 하고,
pFind->next = pNew;

// 새 노드는 NULL을 가리키게 한다.
pNew->next = NULL;
}

// 총 노드의 갯수를 새서 반환하는 함수.
int CountBookNode ( BOOKNODE *pHead )
{
BOOKNODE *pFind;
int nNode = 0;

pFind = pHead->next;

while ( pFind != NULL )
{
nNode++;

pFind = pFind->next;
}

return nNode;
}

/*
void DeleteBookNode ( BOOKNODE *pHead , BOOKNODE node )
{
BOOKNODE *pCurrent;
BOOKNODE *pPrev;
char szTarget[NAME_MAX];

pCurrent = pHead->next; // 현재 노드를 head노드 다음노드를 가르키게함.
pPrev = pHead; // 현재노드의 전 노드를 head노드를 가리키게 함.

while ( pCurrent != NULL )
{
if ( strcmp ( node.m_szPatiCode , pCurrent->m_szPatiCode ) == 0
&& strcmp ( node.m_szDescCode , pCurrent->m_szDescCode ) == 0 )
{
pPrev->next = pCurrent->next;
free ( pCurrent ); // 노드를 메모리에서 삭제한다.
break;
}

pCurrent = pCurrent->next;
pPrev = pPrev->next;
}
}
*/

// 프로그램이 끝날 때 , 메모리에 올라가있는 모든 노드를 삭제하는 함수.
void KillAllBookNode ( BOOKNODE *pHead )
{
BOOKNODE *pCurrent;
BOOKNODE *pPrev;

pCurrent = pHead->next;
pPrev = pHead;

while ( pCurrent != NULL )
{
pPrev = pPrev->next;
pCurrent = pCurrent->next;

free ( pPrev );
}
}

***메인함수부분입니다!!**

#include "common.h"
#include "bookproc.h"
#include "parsedata.h"
#include "linkedbook.h"
#include "linkedmagazine.h"
#include "linkednews.h"
#include "linkedstudent.h"
#include "dataloadmain.h"
#include "main.h"

int main ( void )
{
BOOK *pBookHead;
MAGAZINE *pMagazineHead;
NEWS *pNewsHead;

BOOK book;

pBookHead = (BOOK *) malloc ( sizeof(BOOK) );
pMagazineHead = (MAGAZINE *) malloc ( sizeof(MAGAZINE) );
pNewsHead = (NEWS *) malloc ( sizeof(NEWS) );

printf ( "INPUT TEMP data : " );
scanf ( "%s %s %s %s"
, book.m_szCode
, book.m_szName
, book.m_szAuthor
, book.m_szPublisher
);

AddBookNode ( pBookHead , book );
AddBookNode ( pBookHead , book );
AddBookNode ( pBookHead , book );
AddBookNode ( pBookHead , book );
AddBookNode ( pBookHead , book );
AddBookNode ( pBookHead , book );

KillAllBookNode ( pBookHead );
return 0;
}

shyblue의 이미지

우선, 소스를 올리실땐   로 감싸서 올려주시구요.

Dobule linked list군요. 그렇다면, 지우실때, 맨 마지막 포인트로 이동하시고, current를 free하시는게 좋습니다.
그리고, 특정한 포인터를 하나 만드셔서, 항상 끝을 지정하게 하는 방법도 좋습니다.

Booknode *last = NULL;
int add_book_node( Booknode *p_curr )
{
  .
  .
  .
  last = *p_curr;
}
 
int KillAllNode( Booknode *pHead )
{
  while( last && last->pPrev )
  {
    last = last->pPrev;
    free( last->pNext );
  }
}

대충 생각나는대로 적은 코드라 오류가 있을겁니다. 뭐, 결론은 마지막 노드를 기억하고 있고, 마지막 노드부터 역순으로 free 하는것이 편할 수도 있다라는겁니다.

時日也放聲大哭

時日也放聲大哭

jskim7998의 이미지

void KillAllBookNode ( BOOKNODE *pHead )
{
BOOKNODE *pCurrent;
BOOKNODE *pPrev;

pCurrent = pHead->next;
pPrev = pHead;

while ( pCurrent != NULL )
{
pPrev = pPrev->next;
pCurrent = pCurrent->next;

free ( pPrev );
}
}

pPrev의 next를 pPrev로 해서 pPrev를 지웠는데 다음 loop에 pPrev의 next를 사용하려면 pPrev는 이미 지워졌기 때문에 에러가 생기는거 같습니다.

위 부분을 다음과 같이 수정하시면 될듯합니다.

void KillAllBookNode ( BOOKNODE *pHead )
{
BOOKNODE *pCurrent;
BOOKNODE *pTemp;

pCurrent = pHead->next;

while ( pCurrent != NULL )
{
pTemp = pCurrent;
pCurrent = pCurrent->next;

free ( pTemp );
}
}

====================================
BornAgain !!
Email: jskim98@gmail.com
====================================

====================================
BornAgain !!
Email: jskim98@gmail.com
====================================

jskim7998의 이미지

그리고 위의 예제는 doubly linked list는 아닌거 같습니다.
next 만 있으니까요 pre 가 있으면 doubly linked list 가 되겠죠

그리고 pHead는 지우는게 아닌게 맞지요? pHeader까지 지워야 한다면
조금 수정되어야 할듯하네요

pCurrent = pHead->next; 를

pCurrent = phead; 로 바꿔야 될듯 합니다.

====================================
BornAgain !!
Email: jskim98@gmail.com
====================================

====================================
BornAgain !!
Email: jskim98@gmail.com
====================================

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.