2014-01-07 2 views
1

내가 여기에 문제를 찾기 위해 노력하고 포인터합니다.분할 오류 -이 기능에 - 포인터에서의 printf 값은

구조체 :

struct dictionary 
{ 
    char word[MAXLETTERS]; 
    char** year; 
    int countyear; 
    char** synonyms; 
    int countsyn; 
    char** def; 
    int countdef; 
    struct dictionary*nexdic; 

}; 

추가 기능 : 코드 (! 구조체 = 링크 목록을 추가 구조체에 값을 삽입하고 사전 적 방법으로 장소를 찾을 수)

void Add(char* word, char * year,int countyear, char*syn, int countsyn, char* def,int countdef, dictionary** head) 
{ 
    dictionary*next; 
    //add new entry 
    dictionary*newentry=(dictionary*)malloc(sizeof(dictionary)); 
    if(CheckNull(newentry)==1) 
     exit(1); 
    int i; 
    char *index; 
    //insert word 
    strcpy(newentry->word,word); 
    //insert year 
    char **toyear=(char **)malloc((countyear+1)*sizeof(char*)); 
    index=year; 
    for(i=0;i<=countyear; i++) 
    { 
     toyear[i]=index; 
     index=NextString(index); 
    } 
    newentry->year=toyear; 
    //insert syn 
    index=syn; 
    char **tosyn=(char **)malloc((countsyn+1)*sizeof(char*)); 
    for(i=0;i<=countsyn; i++) 
    { 
     tosyn[i]=index; 
     index=NextString(index); 
    } 
    newentry->synonyms=tosyn; 
    //insert definition 
    index=def; 
    char **todef=(char **)malloc((countdef+1)*sizeof(char*)); 
    for(i=0;i<=countdef; i++) 
    { 
     todef[i]=index; 
     index=NextString(index); 
    } 
    newentry->def=todef; 
    //set counts 
    newentry->countyear=countyear+1; 
    newentry->countsyn=countsyn+1; 
    newentry->countdef=countdef+1; 
    next=FindPlace(newentry->word,*head); 
    if(next==NULL) 
    { 
     if(*head==NULL) 
      newentry->nexdic=NULL; 
     else 
     { 
      newentry->nexdic=*head; 
     } 
     *head=newentry; 
    } 
    else 
    { 
     newentry->nexdic=next->nexdic; 
     next->nexdic=newentry; 
    } 
} 
+4

글쎄, 당신은 당신이 중 하나가 널 포인터가 있거나 배열 범위를 벗어날 색인하는 귀하의 구조가 채워됩니다 어떻게 표시되지 않습니다. 디버거를 사용하는 법을 배울 시간. – OldProgrammer

+3

아마도'current-> def [i]'가 segfaults가있는 시스템상의 해제 된 항목을 가리 키기 때문일 것입니다. – dasblinkenlight

+1

구조가 사용되기 전에 어떻게 초기화하는지 확인하십시오. 아마도 그것은 VS에서 동작하고 리눅스에서는 작동하지 않을 수 있습니다. 왜냐하면 VS는 (특별히 Debug 버전에서)'current-> nexdic'을 NULL로 초기화 할 수 있고 (current-> nexdic == NULL' true) 그리고 리눅스가'else'로 가서 충돌을 일으킨다. –

답변

0

문제 이하.

while 루프에서 currentcurrent->nexic이되며 NULL이 될 수 없습니다. 다음 반복을 위해 current(current->nexdic에 액세스하려고 시도하는 동안 NULL이며 세그먼트 오류가 발생했습니다.

while(current->nexdic!=NULL) 
    { 
     int i; 
     for(i=0;i<current->countdef; i++) 
      printf("%s\n",current->def[i]); 
     current=current->nexdic; 
    } 

I 프로그램의 로직을 모르겠지만, 대신 current->nexdic

+0

그러면 Visual Studio에서 어떻게 작동합니까? –

+0

나는 그걸 시도했지만 그걸 훔쳐서 돌아온다. –

+0

더 많은 코드를 제공해라. –

0

이 코드의 while(current != NULL)를 확인할 수는 (GCC 4.8.2와 맥 OS X 10.9.1에서 테스트) 작동하는 것 같다 : 그렇다 FindPlace(), CheckNull()NextString() (및 테스트 드라이버, main())처럼 누락 된 함수를 작성하고, 정의에서

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

enum { MAXLETTERS = 32 }; 

typedef struct dictionary 
{ 
    char word[MAXLETTERS]; 
    char **year; 
    char **synonyms; 
    char **def; 
    int countyear; 
    int countsyn; 
    int countdef; 
    struct dictionary *nexdic; 
} dictionary; 

static void PrintDic(dictionary **head) 
{ 
    dictionary *current = *head; 
    while (current != NULL) 
    { 
     printf("%s\n", current->word); 
     current = current->nexdic; 
    } 
} 

static int CheckNull(dictionary *dict) 
{ 
    return dict == 0; 
} 

static char *NextString(char *str) 
{ 
    return strchr(str, ','); 
} 

static dictionary *FindPlace(char *word, dictionary *head) 
{ 
    printf("FP: (%p) [%s]\n", (void *)head, word); 
    dictionary *ohead = 0; 
    while (head != 0 && printf("HW: (%p) [%s]\n", head, head->word) > 0 && strcmp(head->word, word) < 0) 
    { 
     ohead = head; 
     head = head->nexdic; 
    } 
    printf("FP: (%p)\n", (void *)ohead); 
    return ohead; 
} 

static void Add(char *word, char *year, int countyear, char *syn, int countsyn, 
       char *def, int countdef, dictionary **head) 
{ 
    // Create new entry 
    // add new entry 
    dictionary *newentry = (dictionary *)malloc(sizeof(dictionary)); 
    if (CheckNull(newentry) == 1) 
     exit(1); 
    int i; 
    char *index; 
    // insert word 
    strcpy(newentry->word, word); 
    // insert year 
    char **toyear = (char **)malloc((countyear + 1) * sizeof(char *)); 
    index = year; 
    for (i = 0; i <= countyear; i++) 
    { 
     toyear[i] = index; 
     index = NextString(index); 
    } 
    newentry->year = toyear; 
    // insert syn 
    index = syn; 
    char **tosyn = (char **)malloc((countsyn + 1) * sizeof(char *)); 
    for (i = 0; i <= countsyn; i++) 
    { 
     tosyn[i] = index; 
     index = NextString(index); 
    } 
    newentry->synonyms = tosyn; 
    // insert definition 
    index = def; 
    char **todef = (char **)malloc((countdef + 1) * sizeof(char *)); 
    for (i = 0; i <= countdef; i++) 
    { 
     todef[i] = index; 
     index = NextString(index); 
    } 
    newentry->def = todef; 
    // set counts 
    newentry->countyear = countyear + 1; 
    newentry->countsyn = countsyn + 1; 
    newentry->countdef = countdef + 1; 

    // Insert new entry in correct place 
    dictionary *next = FindPlace(newentry->word, *head); 
    printf("Next = %p; head = %p\n", (void *)next, (void *)*head); 
    if (next == NULL) 
    { 
     printf("-1-\n"); 
     newentry->nexdic = *head; 
     *head = newentry; 
    } 
    else 
    { 
     printf("-2-\n"); 
     newentry->nexdic = next->nexdic; 
     next->nexdic = newentry; 
    } 
} 

int main(void) 
{ 
    char line[4096]; 
    dictionary *head = 0; 
    while (fgets(line, sizeof(line), stdin) != 0) 
    { 
     size_t offset = 0; 
     char word[4096]; 
     int nchars; 
     line[strlen(line)-1] = '\0'; 
     printf("Line: [%s]\n", line); 
     while (sscanf(line + offset, "%s%n", word, &nchars) == 1) 
     { 
      printf("Word: [%s]\n", word); 
      char *years = "1990,1999"; 
      char *syns = "a,z"; 
      char *defs = "definition1,definition2"; 
      printf("Old Head = %p\n", head); 
      Add(word, years, 2, syns, 2, defs, 2, &head); 
      PrintDic(&head); 
      printf("New Head = %p\n", head); 
      offset += nchars; 
     } 
    } 
    return 0; 
} 

FindPlace() 반환 할 때 t을 NULL 것을 그는 새로운 노드가 목록의 머리에 있어야하고, 그렇지 않으면 새로운 노드가 리턴 된 노드 포인터 바로 뒤에 삽입되어야하며, 주요 변경 사항은 필요 이상으로 복잡한 'insert at head'를 처리하는 코드에 달려있다. 있다. 더 이상 존재하지 않는 PrintDic()에 재미있는 한주기 for 루프가있었습니다. 당신은 수년간의 동의어 및 정의 정보를 포함시킴으로써 우리에게 불편한 과정을 만들었습니다. 아마도이 문제는 현재 당면한 문제에 중요하지 않았을 것입니다. 운전사는 그것들과 가능한 가장 단순한 일을합니다. 전달 된 문자열은 Add()으로 분할되지 않으므로 첫 해 항목은 모든 항목을 인쇄하고, 두 번째 항목은 첫 번째 항목을 제외한 나머지 항목을 인쇄하는 등의 작업을 수행하며 동의어 및 정의와 유사하게 적용됩니다. 각각의 경우 목록 항목은 쉼표로 구분됩니다.

제자리에 디버그 인쇄 코드가 있습니다. 그것을 제거 할 수 있습니다.

샘플 출력 :

ggg 
Line: [ggg] 
Word: [ggg] 
Old Head = 0x0 
FP: (0x0) [ggg] 
FP: (0x0) 
Next = 0x0; head = 0x0 
-1- 
ggg 
New Head = 0x7f848bc038b0 
fff 
Line: [fff] 
Word: [fff] 
Old Head = 0x7f848bc038b0 
FP: (0x7f848bc038b0) [fff] 
HW: (0x7f848bc038b0) [ggg] 
FP: (0x0) 
Next = 0x0; head = 0x7f848bc038b0 
-1- 
fff 
ggg 
New Head = 0x7f848bc03960 
ccc 
Line: [ccc] 
Word: [ccc] 
Old Head = 0x7f848bc03960 
FP: (0x7f848bc03960) [ccc] 
HW: (0x7f848bc03960) [fff] 
FP: (0x0) 
Next = 0x0; head = 0x7f848bc03960 
-1- 
ccc 
fff 
ggg 
New Head = 0x7f848bd00000 
ddd 
Line: [ddd] 
Word: [ddd] 
Old Head = 0x7f848bd00000 
FP: (0x7f848bd00000) [ddd] 
HW: (0x7f848bd00000) [ccc] 
HW: (0x7f848bc03960) [fff] 
FP: (0x7f848bd00000) 
Next = 0x7f848bd00000; head = 0x7f848bd00000 
-2- 
ccc 
ddd 
fff 
ggg 
New Head = 0x7f848bd00000 
eee 
Line: [eee] 
Word: [eee] 
Old Head = 0x7f848bd00000 
FP: (0x7f848bd00000) [eee] 
HW: (0x7f848bd00000) [ccc] 
HW: (0x7f848be00000) [ddd] 
HW: (0x7f848bc03960) [fff] 
FP: (0x7f848be00000) 
Next = 0x7f848be00000; head = 0x7f848bd00000 
-2- 
ccc 
ddd 
eee 
fff 
ggg 
New Head = 0x7f848bd00000 
aaa 
Line: [aaa] 
Word: [aaa] 
Old Head = 0x7f848bd00000 
FP: (0x7f848bd00000) [aaa] 
HW: (0x7f848bd00000) [ccc] 
FP: (0x0) 
Next = 0x0; head = 0x7f848bd00000 
-1- 
aaa 
ccc 
ddd 
eee 
fff 
ggg 
New Head = 0x7f848be000b0 
bbb 
Line: [bbb] 
Word: [bbb] 
Old Head = 0x7f848be000b0 
FP: (0x7f848be000b0) [bbb] 
HW: (0x7f848be000b0) [aaa] 
HW: (0x7f848bd00000) [ccc] 
FP: (0x7f848be000b0) 
Next = 0x7f848be000b0; head = 0x7f848be000b0 
-2- 
aaa 
bbb 
ccc 
ddd 
eee 
fff 
ggg 
New Head = 0x7f848be000b0 
zzz 
Line: [zzz] 
Word: [zzz] 
Old Head = 0x7f848be000b0 
FP: (0x7f848be000b0) [zzz] 
HW: (0x7f848be000b0) [aaa] 
HW: (0x7f848bc03a10) [bbb] 
HW: (0x7f848bd00000) [ccc] 
HW: (0x7f848be00000) [ddd] 
HW: (0x7f848bf00000) [eee] 
HW: (0x7f848bc03960) [fff] 
HW: (0x7f848bc038b0) [ggg] 
FP: (0x7f848bc038b0) 
Next = 0x7f848bc038b0; head = 0x7f848be000b0 
-2- 
aaa 
bbb 
ccc 
ddd 
eee 
fff 
ggg 
zzz 
New Head = 0x7f848be000b0