2012-03-30 1 views
37
#include "stdio.h" 
#include "string.h" 

main() 
{ 

    char string[] = "october"; // october is 7 letters 

    strcpy(string, "september"); // september is 9 letters 

    printf("the size of %s is %d and the length is %d\n\n", string, sizeof(string), strlen(string)); 

    return 0; 
} 

출력 :SIZEOF STRLEN 대

9 월 크기가 8이고 길이가 9

내 구문 또는 무엇에 문제가 무엇입니까?

+10

'string' 배열의 끝에서 쓰고 있습니다. 이것은 정의되지 않은 동작입니다. 'string'은 8 문자 ("10 월"은 7, 널 종결자는 1) 만 저장할 수 있습니다. 'strcpy'를 호출하면, 10 문자를 쓰고 있습니다 (9 개는 "9", 널 종결자는 1 개). 이것은 배열의 끝을 지나치고 인접한 메모리를 덮어 쓰는 것을 의미합니다. – Marlon

+11

'sizeof'는'strlen'가 실행 시간 인 * compile * time에서 계산됩니다. – Naveen

+5

@Naveen : VLA가 관련되어있는 경우 반드시 그런 것은 아니라는 점에 유의하십시오. – caf

답변

1

대상 배열은 8 바이트 ("10 월"+ \ 0 길이)이고 해당 배열에 9 개의 문자를 넣으려고합니다.

man strcpy : strcpy()의 대상 문자열이 충분히 크지 않으면 아무 일도 일어나지 않을 수 있습니다.

+0

sizeof()의 작업을 이해하기위한 테스트 프로그램입니다. – beparas

33

sizeofstrlen()가 다른 일을 나쁜 먼 길을 냄새 때문에 당신이 정말하고 싶은 것을 알려주세요. 이 경우, 귀하의 선언에서

char string[] = "october"; 

그래서 컴파일러는 string의 크기가 그것은 컴파일 시간에이 작업을 수행 8. 것을 알 수

char string[8] = "october"; 

과 동일합니다.

그러나 strlen()은 런타임에 문자열의 문자 수를 계산합니다. 따라서 strcpy()으로 전화하면 string에 "september"가 포함됩니다. strlen()은 문자를 계산하고 그 중 9 개를 찾습니다. "9 월"을 보유하기 위해 string에 충분한 공간을 할당하지 않았습니다. 이것은 정의되지 않은 동작입니다.

첫 번째 문 문자열의 크기는 7 + 1 컴파일러에 의해 할당 된 때문에

3

출력이 정확한지

두 번째 문 (10 월 컴파일시에 널 (NULL) 종료 7 바이트 & 1 바이트) : 당신은 9 월 복사 (9 바이트에서 8 바이트 문자열); 이 당신을 위해

당신이 예에서는 buffer overflow 문제를 제거해야한다 8 바이트 (여전히 strlen() 9 월 작동하지 않습니다이 널 문자가없는)

+1

문자열 리터럴''september "는 암시 적으로 null 문자를 포함하므로 프로그램이 이미 충돌하지 않았 으면'strlen()'이 작동합니다 'string' 배열의 끝을 지나서) –

-1

당분의 크기를 얻었다. 이를 수행하는 한 가지 방법은 다음과 같습니다. strncpy :

memset(string, 0, sizeof(string)); 
strncpy(string, "september", sizeof(string)-1); 
+1

아니요, 아니요, 아니요. 'strncpy()'는 이름에도 불구하고 ** strings **로 무엇이든 할 수있는 잘못된 도구입니다. 위의 예에서 8 개의 요소 중 어느 것도 0 종결자를 포함하지 않으므로 결과 문자열'string'은 * 문자열이 아닙니다. – pmg

+0

왜 잘못된 도구입니까? 문자열 종료 문제가 해결되었습니다. –

+0

정의에 따라 각 문자열에 존재하는 제로 터미네이터를 설명하지 않기 때문에 문자열에 대한 잘못된 도구입니다 ('strncpy()'디자인은 ... errr ...에 대해서만 유용합니다) * un-terminated 문자열 *). 빈칸이 있는지 확인하고'strcpy()'를 사용하십시오 (BSD-isms를 사용할 수 있다면'strlcpy()'를 사용하십시오). – pmg