2013-02-13 4 views
-1

파이프에서 문자를 읽고 결과 문자열에 넣어 병합을 구현하려고합니다. 세그먼트 화 오류가 계속 발생하며 문제의 원인을 디버깅하는 데 문제가 있습니다. 이 함수에 대한 호출을 제거하면 문제가 사라져 여기에 잘못된 내용이 표시됩니다.C char 배열과 포인터 - merge of mergeort

MAX_LENGTH는 1024로 설정되어 있으며 약 30 자만 정렬하므로 믿을 여유가 있어야합니다.

int merge(char *result, int *leftpipefd, int *rightpipefd) { 
char left[MAX_LENGTH/2]; 
char right[MAX_LENGTH/2]; 
int leftpos = 0; 
int rightpos = 0; 
int resultpos = 0; 

read(leftpipefd[READ_END], left, MAX_LENGTH/2); 
read(rightpipefd[READ_END], right, MAX_LENGTH/2); 

int leftlen = strlen(left); 
int rightlen = strlen(right); 

while (leftpos < leftlen || rightpos < rightlen) { 
    if (leftpos < leftlen && rightpos < rightlen) { 
     if (left[leftpos] <= right[rightpos]) { 
      result[resultpos] = left[leftpos]; 
      resultpos++; 
      leftpos++; 
     } else { 
      result[resultpos] = right[rightpos]; 
      resultpos++; 
      rightpos++; 
     } 
    } else if (leftpos < leftlen) { 
     result[resultpos] = right[rightpos]; 
     resultpos++; 
     rightpos++; 
    } else if (rightpos < rightlen) { 
     result[resultpos] = left[leftpos]; 
     resultpos++; 
     leftpos++; 
    } 
} 

return EXIT_SUCCESS; 
} 

사람이 내가 뭘 잘못 볼 수 있을까요?

+1

디버거를 사용해보십시오. strlen()에 대한 호출은 어떤 값을 반환합니까? 당신의'왼쪽 '과'오른쪽' "문자열"은 null로 끝났습니까? – MatthewD

+0

이것을 디버깅하는 가장 좋은 방법은 무엇입니까? 내 표준 입력과 표준 출력은이 과정에서 파이프에 연결되므로 인쇄 방법을 모른다. – Deathcalibur

+0

@Deathcalibur는 "디버거를 사용합니다." 디버거는 단지 print 문을 쓰는 것이 아니라 실제 프로그램입니다.gdb – djechlin

답변

0

길이가 N 인 버퍼에 N 문자를 읽는 경우 strlen 기능이 제대로 작동 할 것이라고 예상하는 경우 ... 의 버퍼가 있어야합니다. 따라서 문자는 \0 문자로 끝날 수 있어야합니다. 즉 거기, 다음에 일어날 것을 알고있는 ...

0

여러 가지 ... 때 http://linux.die.net/man/2/read에서

...

읽기() 파일 기술자에서 count 바이트까지 읽기를 시도 fd는 buf에서 시작하는 버퍼에 저장된다. count가 0이면 read()는 0을 반환하고 다른 결과는 반환하지 않습니다. count가 SSIZE_MAX보다 큰 경우 결과는 지정되지 않습니다.

MAX_LEN은 무엇인가요? SSIZE_MAX보다 큰가요? 그렇다면 정의되지 않은 동작이 발생합니다.

read()에 입력이 없으면 아무 것도 읽지 않고 ... 초기화하지 않은 버퍼는 변경되지 않습니다. 버퍼를 초기화해야합니다. 오류에 같은 페이지에서

...

는, -1이 반환되고, errno는 적당한 값으로 설정된다.

읽기에 실패하면 버퍼가 아직 정의되지 않았거나 초기화되지 않았지만이 상황을 감지하거나 처리하지는 않습니다. read()의 직후에 에러 처리 코드가 필요합니다.

또한 동일한 설명서 페이지에는 read()의 버퍼가 null로 종료된다는 표시가 없습니다. Floris가 지적했듯이, 이것은 여러분의 strlen()이 할당 된 버퍼의 끝을지나 계속해서 읽는 것을 의미합니다.

동안 (leftpos < leftlen || rightpos < rightlen) {

이 라인 에러 일 수있다. leftpos> = leftlen이지만 rightpos가 < rightpos 인 경우 while 블록의 본문을 입력합니다. 그런 식으로 잘못된 메모리에 액세스하기 시작할 것입니다. &&이 정말로 필요합니까?