2014-12-20 2 views
2

그래서 주어진 텍스트 줄을 목록에 저장하는 텍스트 버퍼를 만들려고합니다. 현재 스왑 함수를 작성하고 있지만 특정 선을 조정하고 조정하면 세그먼트 오류가 발생합니다.Seg 오류 11 문자열 내용을 바꿀 때

이 현재 내가 사용 swapfunction입니다 : 다음 스왑

char text[] = "0. She walks in beauty, like the night\n" 
       "1. Of cloudless climes and starry skies;\n" 
       "2. And all that’s best of dark and bright\n" 
       "3. Meet in her aspect and her eyes;\n" 
       "4. Thus mellowed to that tender light\n" 
       "5. Which heaven to gaudy day denies.\n" 
       "6. One shade the more, one ray the less,\n" 
       "7. Had half impaired the nameless grace\n" 
       "8. Which waves in every raven tress,\n" 
       "9. Or softly lightens o’er her face;\n" 
       "10. Where thoughts serenely sweet express,\n"; 

및 수행 :

swapTB(tb, 4, 7); 
swapTB(tb, 2, 9); 
swapTB(tb, 2, 10); 

를 내가 시도하고이 텍스트를 공급하는 경우

void swapTB (TB tb, int pos1, int pos2) { 

if (tb == NULL) { 
    abort(); 
} 

if (pos1 < 0 || pos1>tb->size || pos2<0 || pos2>tb->size) { 
    printf("error: lines are out of range!\n"); 
    abort(); 
} 

link line1 = findLine(tb, pos1); 
link line2 = findLine(tb, pos2); 

char *temp = (char *)malloc((strlen(line1->line) + 1) * sizeof(char)); 
strcpy(temp,line1->line); 
strcpy(line1->line, line2->line); 
strcpy(line2->line,temp); 

free(temp); 

} 

잘 작동하고이 출력을 얻습니다.

012 나는 그런 9 호선 단축으로, 텍스트를 약간 변경하면 33,

그러나 :

char text[] = "0. She walks in beauty, like the night\n" 
       "1. Of cloudless climes and starry skies;\n" 
       "2. And all that’s best of dark and bright\n" 
       "3. Meet in her aspect and her eyes;\n" 
       "4. Thus mellowed to that tender light\n" 
       "5. Which heaven to gaudy day denies.\n" 
       "6. One shade the more, one ray the less,\n" 
       "7. Had half impaired the nameless grace\n" 
       "8. Which waves in every raven tress,\n" 
       "9. Or softly lightens o’er\n" 
       "10. Where thoughts serenely sweet express,\n"; 

을 나는 때때로 잘 작동하는 분할 오류 (11)

이 지속적으로 일어나고있다을 얻을 때로는 세분화 오류가 발생하고 다른 시간에는 실행되지만 최종 출력에는 중복이 있습니다.이 값은 함수에 제공하는 텍스트에 따라 다릅니다.

텍스트 그런데, 이와 같은 구조체에 저장되고 :

typedef struct textNode *link; 

struct textNode { 
    char *line; 
    link next; 
}; 

struct textbuffer{ 
    link head; 
    link last; 
    int size; 
}; 

EDIT :

link newLine(char text[], int start, int i) { 

    link newLine = malloc(sizeof(*newLine)); 
    assert(newLine != NULL); 

    newLine->line = extract(text, start, i); 
    //printf("newline is %s\n", newLine->line); 
    newLine->next = NULL; 

    return newLine; 

} 

추출 기능

:

함수 개행을 할당

char* extract(const char* src, int start, int end) { 

    return strndup(src + start, (end - start)+1); 
} 

functi findLine

link findLine(TB tb, int pos) { 

    link curr = tb->head; 
    int index = 0; 

    while (index != pos) { 
     curr = curr->next; 
     index++; 
    } 

    return curr; 
} 
+0

'line' 멤버를 어떻게 초기화합니까? 코드 pealse 게시하십시오. –

+0

@iharob 나는 사람들이 노골적으로 게시 한 해결책으로 해결했습니다! 하지만 여전히 궁금하다면 strndup과 while 루프를 사용하여 개행 후에 모든 장소를 인덱싱합니다. – reetyn

+0

그러면 메모리 누수가 발생했습니다. –

답변

1

것은 올바르게 스왑 작업을 작성해야이 문제 중 하나를 재 할당 포인터를 수정하거나 내용을 교환하는 대신 포인터 스왑을 수행합니다.당신은 문자열 자신을 복사 할 필요가 없습니다 볼 수 있듯이 대신이 코드의

char *temp = (char *)malloc((strlen(line1->line) + 1) * sizeof(char)); 
strcpy(temp,line1->line); 
strcpy(line1->line, line2->line); 
strcpy(line2->line,temp); 

char *temp = line1->line; 
lin1->line = line2->line; 
line2->line = temp; 

이 있어야한다. 포인터를 바꿔 쓰면 충분합니다.

size 데이터 유형을 int으로 정의 할 때마다 0보다 작은 지 여부를 확인하는 의미가 없음을 고려하십시오. 크기가 타입으로 정의 된 경우 훨씬 더 좋을 것입니다. size_t

+0

! 감사합니다 – reetyn

+0

@reetyn 환영합니다. :) –

1

에 문제는 당신이 때때로 이전에 짧은 문자열에 할당 된 공간으로 더 긴 문자열에서 데이터를 기록 할 것으로 것으로 보인다.

char *temp = malloc(strlen(line1->line) + 1); // No need to cast or multiply by sizeof(char) 
strcpy(temp,line1->line); 
strcpy(line1->line, line2->line); 
strcpy(line2->line,temp); 
free(temp); 

귀하의 코드가 line1->line의 데이터에 대한 temp에 충분한 공간이 있는지 확인합니다,하지만 충분한 공간이 거기에 있음을 가정합니다 스왑을 수행하는 코드,이 다섯 줄을 IE는 문제가있다 temp의 데이터가 line2->line이고 line2->line의 모든 문자에 충분한 공간이 line1->line에 있습니다.

char *temp = line1->line; 
line1->line = line2->line; 
line2->line = temp; 
+0

이것은 좋은 충고입니다, 특별히'내용을 교환하는 대신 포인터를 교환하십시오'부분입니다. 그것은 이것을하는 방법입니다. –

+0

감사합니다. 문제가 해결 된 ~ – reetyn