2013-08-21 5 views
1

어제 C를 배우기 시작 했으므로 사소한 질문 일 수 있지만 여전히 이해가 가지 않습니다. (또는 후) 문자열을 concating 때두 개의 문자열을 작은 배열로 연결하는 경우 segfault

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char text[8]; 
    strcpy(text, "Lorem "); 
    puts(text); 
    strcat(text, "ipsum!"); 
    puts(text); 
    return 0; 
} 

이 세그먼트 오류가 발생합니다 :

의 나는 다음과 같은 코드가 있다고 가정 해 봅시다

. 그러나 text의 크기를 8에서 9로 변경하면 그렇지 않습니다.

내가 틀렸다면 정정 해줘 그러나 이것은 옳은 생각입니다하십시오 : - "! ipsum의"

"LOREM"(\ 0 또는 7) 크기 6
- 크기 6 (또는 7이 \ 0)
"Lorem ipsum!" - 크기 12 (또는 13이 \ 0)

그럼 8/9은 어디서 나왔습니까? 이 문제는 strcat의 구현으로 인해 발생합니까? 아니면 최소 배열 길이 같은 것이 있습니까? 아니면 어리 초한 초보자의 실수를 저지르고 있습니까?

미리 감사드립니다.

+4

[정의되지 않은 동작 (http://en.wikipedia.org/wiki/Undefined_behavior) –

+0

실행 Valgrind의에서이 (http://valgrind.org) 당신은 문제가 모두 있다는 것을 볼 수 있습니다 사례. – alk

+1

그리고 "8/9는 어디서 왔는가"라는 질문에 대한 답은 특정 컴파일러가 8 바이트 청크로 메모리를 할당 할 가능성이 있습니다. 따라서 텍스트 [8]은 8 바이트를 할당합니다. text [9]는 최대 16 바이트를 반올림합니다. 물론 이것은 구현에 따라 다르며, 항상 이것을 수행하는 컴파일러를 믿지 않아야합니다! –

답변

3

적어도 Linux에서는 충돌이 발생하지 않는 순수한 행운입니다. *** stack smashing detected ***을 얻습니다.

문자열을 다른 문자열에 추가하려는 경우에도 후자의 저장소가 부족한 경우에도 마찬가지입니다. 이것은 정의되지 않은 동작의 예입니다 (주석에서 지적한대로).

C는 프로그래머가 프로그램에있는 것을 항상 신뢰하는 언어이므로 컴파일 할 때 경고 메시지가 표시되지 않을 수도 있습니다.

버퍼에 충분한 저장소가 있는지 항상 확인하십시오. C에서 안전 동작을 보장하는 시설이 거의 없으므로 minimum array length과 같은 것을 가정하지 마십시오.

+0

글쎄, 자바와 일부 스크립팅 언어에 대한 경험이 있기 때문에 익숙해 져야한다고 생각합니다. 감사. – Griddo

+0

아, 절대적으로 Java는 매우 특별하며 예를 들어 unitialised 원시 유형을 사용하도록 허용하지 않습니다. 모든 경고를 사용 가능하게 설정하면 'C'에서 경고를받을 수 있지만 여전히 실행할 수 있습니다 당신이하고있는 것을 당신이 알고 있다고 가정하는 코드 :) 그리고 당신은 당신을위한 장면의 뒤에서 너무 많이하는 스크립팅 언어의 용서하는 행동을 결코 얻지 못합니다. C는 매우 맨다. – Nobilis

3

배열의 끝을 오버런하면 프로그램의 정의되지 않은 동작이 발생합니다. 이것은 그것이 당신이 기대하는 것을 할 수도,하지 않을 수도 있음을 의미합니다. 마치 정의되지 않은 동작을 호출하지 않은 것처럼 실행될 수 있습니다. 그것은 추락 할 수도 있습니다. 하드 드라이브를 다시 포맷 할 수 있습니다. 프린터에 빈 페이지가 인쇄 될 수 있습니다. 당신이 그것을 실행할 때 그것은 그 모든 것을 할 것입니다.

알 수 없습니다. 그것이 '정의되지 않은 행동'입니다. 정의되지 않음.

나는 행동에 대한 설명을 줄 수는 있지만, 도움이되지 않을 것이며, 하드웨어와 구현에 따라 다릅니다.

0

원하는 크기로 malloc 할 수 있습니다. 심지어 추가 입력에 따라 다시 할당 할 수도 있습니다.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() 
{ 
    char *text; 
    text = (char *) malloc(sizeof(char) * 12); 
    memset(text, 0x0, sizeof(char) * 12); 
    sprintf(text, "%s", "Lorem "); 
    puts(text); 
    sprintf(text, "%s%s", text, "ipsum!"); 
    puts(text); 
    return 0; 
}