2013-03-27 3 views
0

아래 함수는 문자열을 연결된 목록에서 오름차순으로 정렬하려고합니다. 새 목록을 반환하면 손상됩니다.strcpy는 char 배열 (문자열 값)을 손상시킵니다.

void* order(void *ptr){ 
    struct wordlist *head; 
    head = (struct wordlist *) ptr; 

    struct wordlist *first = (struct wordlist*)malloc(sizeof(struct wordlist)); 
    struct wordlist *second = (struct wordlist*)malloc(sizeof(struct wordlist)); 
    struct wordlist *temp = (struct wordlist*)malloc(sizeof(struct wordlist)); 

    first = head; 

    int j = 1; 
    while(first != NULL){ 
     second = first->next; 

     while(second != NULL){ 
      if(strcmp(first->word, second->word) > 0){ 
       if(temp->word == NULL){ 
        temp->word = malloc(sizeof(first->word)); 
       } 
       else{ 
        if(realloc(temp->word, sizeof(first->word)) != NULL){ 
         strcpy(temp->word, first->word); 
        } 
       } 

       if(realloc(first->word, sizeof(second->word)) != NULL){ 
        strcpy(first->word, second->word); 
       } 

       if(realloc(second->word, sizeof(temp->word)) != NULL){ 
        strcpy(second->word, temp->word); 
       } 

       free(temp); 
      } 
      second = second->next; 
     } 
     j++; 
     first = first->next; 
    } 
} 

예를 들어, 입력 후 출력은 위의 예제 코드에 시도되지

messi 
ŽŽŽ 
ronaldo 

처럼 보이지만 그것은 당신에게 단서를 줄 것이다

piero 
ronaldo 
messi 

될 경우 . 나는 기억의 할당과 함께 뭔가가 있다고 생각하지만 그것을 찾을 수 없었다. 그건 그렇고, 때로는 단어가 비어 있습니다.

struct wordlist{ 
    char *word; 
    struct wordlist *next; 
}; 
+1

링크 된 목록을 정렬하려면이 메모리 할당을 모두 수행 할 필요가 없습니다. 뭔가를 이동할 때마다 '다음'포인터를 바꿀 수 있어야합니다. 관련된 메모에서'second '에 메모리를 할당하면'second = first-> next;로 즉시 이것을 유출합니다. – lxop

+1

포인터를 바꿀 수 있다는 것을 알고 있습니까? 그들을 옮기기 위해'realloc'과'strcpy'를 할 필요가 없습니다. – paddy

답변

1

당신은 주변에 임시 처음에 문자열을 복사하지 마십시오 다음과 같이

또한, 단어 목록입니다. temp->wordNULL 인 경우

  if(temp->word == NULL){ 
       temp->word = malloc(sizeof(first->word)); 
       // You forgot to copy!! 
      } 
      else{ 
       if(realloc(temp->word, sizeof(first->word)) != NULL){ 
        strcpy(temp->word, first->word); 
       } 
      } 

참조가되는 것이 처음으로 (당신이 정의되지 않은 동작을 얻을 것이다 아직 실제로 temp 구조체를 삭제하지 않도록주의)되어야한다, 당신은하지 않습니다 그것을 복사하십시오. 빠른 수정은 후에 strcpy을 수행하는 것입니다.

realloc 통화가 모두 잘못되었습니다. 문자열의 크기를 얻으려면 sizeof을 사용할 수 없습니다. strlen을 사용하고, 문자열 터미네이터에 여분의 바이트를 추가하는 것을 잊지 마십시오.

또한 firstsecond을 할당하면 안됩니다. 이들은 데이터 구조의 반복자입니다. 당신이하는 첫번째 일은 그들의 가치를 버려서 당신이 기억을 누설하는 것입니다. 나중에 temp 구조는 free이고 temp->word 구조체를 잊지 마세요.

작업을 마친 후에는이 모든 것을 중지하십시오 mallocstrcpy !!!

문자열을 이동하려면 포인터를 움직여야합니다. 재 할당 또는 사본 필요 없음. 이렇게하면 코드를 몇 줄로 단순화 할 수 있습니다.

오, 당신도 당신의 기능에서 얻은 가치를 return에 잊었습니까?

+0

"if strcmp {}"부분의 모든 내용을 삭제하고 세 줄로 포인터 스왑을 수행했습니다. 그것은 매력처럼 작동합니다. 이 문제를 해결하는 데 몇 시간을 낭비했지만 너무 단순 해졌습니다. 고맙습니다. – gzg

+1

문제 없습니다. 그것은 낭비되지 않았습니다 - 당신이 경험에서 많은 것을 배웠 으면 좋겠다 =) – paddy