2014-02-26 1 views
3
char r[40]; 
strcpy(r,"abcdef"); 
strcat(r,r); 

내 프로그램이 세 번째 줄에서 충돌합니다.동일한 배열을 두 매개 변수로 사용하면 strcat()가 충돌합니다.

strcat (r, r) 바꾸기; strcat (r, "abcdef")에 의해; 그래도 괜찮 았어. 왜 그거야? strcat(3) 따르면

+0

'strcat()'을 직접 구현하는 방법을 생각하면 좋은 학습 경험이 될 것입니다. (아주 간단한 함수입니다). 그런 다음 구현에서 자체 연결을 처리하는지 확인하고 자체 처리를 처리 할 수 ​​있도록해야하는지 확인하십시오. 그런 다음'strcpy() '를 호출하는 모든 사람들이 거의 사용되지 않는 자체 연결과 같은 기능을 지원하는 비용을 지불해야하는지 생각해보십시오. –

답변

0

strcat()은 입력에서 \0 종결자를 찾을 때까지 입력을 읽고 출력에 복사합니다. 입력 및 출력에 동일한 배열을 지정하면 입력을 읽는 동안 입력을 수정하게됩니다.

당신은 strcat()의 컴파일러의 특정 구현을 확인해야합니다,하지만 당신은 다음과 같은 간단한 구현을 통해 추적 할 경우, 당신은 왜 당신의 코드 충돌 잠시 후 볼 수 다음 while (*dest != 0) 루프 후

char *strcat(char *dest, const char *src) 
{ 
    char *ret = dest; 
    if (dest && src) 
    { 
     while (*dest != 0) 
      ++dest; 
     while (*str != 0) 
      *dest++ = *src++; 
     *dest = 0; 
    } 
    return ret; 
} 

, dest은 이제 입력의 \0 터미네이터를 가리 킵니다. while (*str != 0) 루프의 첫 번째 반복은 해당 터미네이터를 a으로 바꿔 루프가 더 이상 멈추지 않게합니다. 결국 루프는 입력 경계를 초과하여 주변 메모리 읽기를 시작하고 잘못된 메모리를 치기 전에 다른 \0 바이트를 찾지 못하면 결국 충돌합니다.

3

:

strcat() 함수는 다음 최종 도착 끝에 널 종료 바이트 ('\ 0') 겹쳐 최종 도착 문자열에 SRC 캐릭터를 추가하고,이 널 종료 바이트를 추가 . 문자열이과 겹치지 않을 수 있으며 dest 문자열에 결과에 충분한 공간이 있어야합니다.

2

이 예제에서 strcat가 char * r의 종료 null을 덮어 쓰는 이유는 무엇입니까? 그런 다음 r을 검색하여 루프를 덮어 쓰고 결국 안전하지 않은 메모리로 겹쳐서 덮어 씁니다. (정확히 스택의 방향에 따라 달라집니다)

이 솔루션은 strncat (r, r, strlen (r))과 유사합니다. 널을 덮어 쓰기 전에 R의 길이를 포착합니다.

2

답 답. 그냥 약간의 "그래픽"설명을 추가하고 싶었습니다.

strcat의 구현 방법을 생각하면 원본 문자열의 첫 번째 문자에서 포인터를 초기화하고 소스 문자가 null 바이트에 도달 할 때까지 문자 단위로 이동합니다. 그러나 원본 문자열과 대상 문자열이 동일하기 때문에 다음과 같은 경우가 발생할 수 있습니다.

메모리는 다음과 같이 시작은 :

a b c d e f \0 

소스 (S)와 최종 도착 (d)는 함수에 진입 a에 두 점의 포인터. 의 최종 도착 포인터 끝으로 이동하고 우리는 복사 할 준비

s   d 
a b c d e f \0 

    s   d 
a b c d e f a 

    s   d 
a b c d e f a b 

     s   d 
a b c d e f a b c 

     s   d 
a b c d e f a b c d 

      s   d 
a b c d e f a b c d e 

      s   d 
a b c d e f a b c d e f 

       s   d 
a b c d e f a b c d e f a 

당신이이 처음에 구타했기 때문에 소스 포인터, 그 널 종료 바이트에 도달하지 않을 것을 볼 수 있습니다. 결국 우리는 여기서 우주를 다 써 버릴 것입니다.

그렇기 때문에 strcat의 정의는 두 문자열이 겹치지 않도록합니다. 이런 식으로 구현하면 기본 구현을 자유롭게 사용할 수 있습니다.

관련 문제