2011-05-01 2 views
0

저는이 코드를 시도하고 있습니다. 때때로 작동하지만 가끔은 잘 동작하지 않습니다! 구조체에 대한 포인터를 반환하는 함수를 만든 다음 새 구조체에 단어를 추가하는 함수 (추가)를 만듭니다.여기에 무슨 문제가 있습니까? [동적 구조 C]

typedef int boolean; 
boolean first = TRUE; 
typedef struct s_Reg 
{ 
    char *str; 
    struct s_Reg *next; 
} Reg; 
Reg* CreateList() 
{ 
    Reg *list = (Reg*)malloc(sizeof(Reg)); 
    list -> str = (char*)malloc(sizeof(char)); 
    if (list != NULL && list -> str) 
     return list; 
    else 
     return NULL; 
} 
boolean Add(Reg *list, char *str) 
{ 
    Reg *pos = list; 
    if (first == TRUE) 
    { 
     list -> str = (char*)malloc(sizeof(char)); 
     if (list -> str != NULL) 
     { 
      list -> str = str; 
      list -> next = NULL; 
      first = FALSE; 
     } 
     else 
      return FALSE; 
    } 
    else 
    { 
     while (pos -> next != NULL) 
      pos = pos -> next; 
     pos -> next = (Reg*)malloc(sizeof(Reg)); 
     if (pos -> next != NULL) 
     { 
      pos = pos -> next; 
      pos -> str = (char*)malloc(sizeof(char)); 
      if (pos -> str != NULL) 
      { 
       pos -> str = str; 
       pos -> next = NULL; 
      } 
      else 
       return FALSE; 
     } 
     else 
      return FALSE; 
    } 
    return TRUE; 
} 
int main() 
{ 
    boolean b; 
    int  i; 
    char *str; 
    Reg  *words = CreateList(); 
    str = malloc(sizeof(char)); 
    if (words == NULL) 
     return -1; 
    for (i = 1; i <= 3; ++i) 
    { 
     printf("\nword: "); 
     gets(str); 
     b = Add(words, str); 
     if (b == FALSE) 
      return -1; 
     str = malloc(sizeof(char)); 
    } 
    while (words != NULL) 
    { 
     printf("Word: %s\n", words -> str); 
     words = words -> next; 
    } 
    free(str); 
    str = NULL; 
    free(words); 
    words = NULL; 
    return 0; 
} 

내가

Add(words, "blablablablablabla"); 
Add(words, "blablaasfsafdblblablaasfbla"); 
Add(words, "blablaasfsafdblblablaasfblaasdfasfasdf"); 

그것은 잘 때마다 작동 (데이터를 삽입하는 사용하지 않는) 이렇게 할 경우! 하지만 FOR를 사용하여 데이터를 삽입하면 긴 문자열을 삽입하는 경우가 있습니다!

/////// ** 편집 //////// **

글쎄, 내가 모든 질문을 읽고, 당신에게 모두 감사합니다. 코드를 다시 작성하고 작동하는 것 같습니다 (그러나 더 좋을 수 있다고 생각합니다)

이것은 내 최종입니까? 코드 :

#include "stdio.h" 
#include "stdlib.h" 
#include "string.h" 

#define TRUE 1 
#define FALSE -1 

typedef int boolean; 

boolean first = TRUE; 

typedef struct s_Reg 
{ 
    char *str; 
    char *str2; 
    char *str3; 

    struct s_Reg *next; 
} Reg; 

Reg* CreateList() 
{ 
    Reg *list = (Reg*)malloc(sizeof(Reg)); 

    if (list != NULL) 
     return list; 
    else 
     return NULL; 
} 

boolean Add(Reg *list, char *str, char *str2, char *str3) 
{ 
    Reg *pos = list; 

    if (first == TRUE) 
    { 
     list -> str = (char*)malloc(strlen(str) + 1); 
     list -> str2 = (char*)malloc(strlen(str2) + 1); 
     list -> str3 = (char*)malloc(strlen(str3) + 1); 
     if (list -> str == NULL || list -> str2 == NULL || list -> str3 == NULL) 
      return FALSE; 

     sprintf(list -> str, str); 
     sprintf(list -> str2, str2); 
     sprintf(list -> str3, str3); 
     list -> next = NULL; 

     first = FALSE; 
    } 
    else 
    { 
     while (pos -> next != NULL) 
      pos = pos -> next; 

     pos -> next = (Reg*)malloc(sizeof(Reg)); 
     if (pos -> next != NULL) 
     { 
      pos = pos -> next; 

      pos -> str = (char*)malloc(strlen(str) + 1); 
      pos -> str2 = (char*)malloc(strlen(str2) + 1); 
      pos -> str3 = (char*)malloc(strlen(str3) + 1); 
      if (pos -> str == NULL || pos -> str2 == NULL || pos -> str3 == NULL) 
       return FALSE; 

      sprintf(pos -> str, str); 
      sprintf(pos -> str2, str2); 
      sprintf(pos -> str3, str3); 
      pos -> next = NULL; 
     } 
     else 
      return FALSE; 
    } 

    return TRUE; 
} 

int main() 
{ 
    boolean b; 
    int  i; 
    char str[64], str2[64], str3[64]; 
    Reg  *words = CreateList(); 

    if (words == NULL) 
     return -1; 

    for (i = 1; i <= 3; ++i) 
    { 
     printf("\nstr1: "); 
     gets(str); 
     printf("\nstr2: "); 
     gets(str2); 
     printf("\nstr3: "); 
     gets(str3); 

     b = Add(words, str, str2, str3); 
     if (b == FALSE) 
      return -1; 
    } 

    while (words != NULL) 
    { 
     printf("str1: %s\n", words -> str); 
     printf("str2: %s\n", words -> str2); 
     printf("str3: %s\n\n", words -> str3); 

     words = words -> next; 
    } 

    free(words); 
    words = NULL; 

    return 0; 
} 
+0

충돌이 발생하면 어떤 메시지가 나타 납니까? 디버거에서 프로그램을 단계별로 실행 해 보았습니까? 또는 도움이되는'printf' 문을 추가하여 진행 상황을 모니터 할 수 있습니까? –

답변

0
str = malloc(sizeof(char)) 

참조, 1 바이트 메모리를 할당합니다. str이 함수를 가져 오면 정의되지 않은 동작이 발생합니다.

+0

이것이 문제의 해결책이라고 생각한다면 잘못 생각한 것입니다. 물론 틀렸지 만 코드가 현재 가지고있는 것처럼 즉시 메모리를 버리면 할당 할 메모리 양이 중요한 이유는 무엇입니까? –

+0

@ david 당신은 그에게 훌륭한 해결책을주었습니다. 심지어 당신의 대답에 +1을 줬습니다. 그러나 그가 묻는 것은 여기서 잘못된 것이고 나는 그것을 지적했다. 나는 그에게 올바른 해결책 중 하나를 보여주기보다는 그에게 배움의 기회를 남겨 두는 것이 낫다고 생각합니다. :) –

+0

이것은 잘못된 것의 시작에 불과합니다. 'Add()'함수를 살펴 보자. malloc을 호출하여'list-> str'을 할당 한 다음 즉시'list-> str'을 다른 것으로 덮어 씁니다. 이것은 C 문자열의 작동 방식에 대한 오해를 잘 보여줍니다. 내 대답은 훨씬 향상 될 수 있지만 최소한이 코드의 많은 문제점 중 하나만 강조했음을 지적해야합니다. 글쎄, 그건 내 의견이야 !! –

4

전체 문자열 처리 코드가 잘못되었습니다. 한 문자에만 메모리를 할당합니다. 그런 다음 그 기억을 누설합니다.

이와 같은 코드를 해결하기 전에 기본으로 돌아가서 malloc()strncpy()을 사용하는 방법을 알아야합니다.

예를 들어, 도움이 될 루틴은이 될 것이다 :

char* AllocStr(char *str) 
{ 
    size_t len; 
    char *result; 
    len = strlen(str)+1;//add one for zero-terminator 
    result = malloc(len); 
    return strncpy(result, str, len); 
} 

이 입력 매개 변수의 길이에 따라 새로운 문자열에 대한 메모리를 할당 한 다음 복사 입력 매개 변수의 내용에 새로운 캐릭터 라인

struct의 str 필드에 할당 할 때마다 다음과 같은 코드를 사용해야합니다.

코드에 다른 버그가 많이 있지만 지금 당장 포인터를 놓고 메모리 할당/할당 취소 등에 대한 이해를 향상시켜야한다고 생각합니다. 현재 사용하고있는 간단한 문제를 찾을 수 있습니까? 이 코드를 디버그하려고하면 매우 비효율적 일 것입니다.

참고 :이 샘플에서는 설명의 편의를 위해 오류를 검사하지 않습니다.

+0

고마워요, 유용합니다. – Ulrira

0

또한 메모리 관리를 검토해야합니다. 실제로 목록을 만들면 문자열에 메모리가 할당됩니다. 그런 다음 Add 함수가 호출되고 첫 번째 == TRUE 일 때 메모리를 할당합니다. 이미 할당 된대로 올바르지 않습니다.

관련 문제