코드가 정의되지 않은 동작을 호출하여 일부 출력을 생성하는 이유 또는 다른 출력이 무의미하다는 것을 설명하려고 시도합니다. 당신은 <stdio.h>
,도 <string.h>
에 포함되지 않습니다
:
는 여기에 문제가 있습니다. 이전에 정의되지 않은 함수 호출은 OK가 아닙니다. 정의되지 않은 동작을 방지하려면 적절한 헤더 파일을 포함하십시오.
char dest[0];
은 0
크기의 배열을 정의합니다. 이러한 객체는 액세스 할 수 없으며 주소가 의미있는 것이 아니어도 액세스 할 수 없습니다. gcc
및 clang
이 허용하지만 C 표준을 확장 한 것입니다. 이 정의는 오타처럼 보이지만, 바보 같은 버그를 방지하는 유용한 경고를하려면 gcc -Wall -W
또는 clang -Weverything
을 사용하십시오.
strncpy(dest, src, 4);
은 dest
길이가 4
보다 작기 때문에 정의되지 않은 동작을 호출합니다. 소스 문자열의 길이가 size 인수보다 크거나 같으면 strncpy
이 null이 아니므로 의 길이가 4
인 경우 동작은 여전히 오류가 발생합니다. 여기 "santosh"
의 길이는 7
이므로 dest
문자는 s
, a
, n
및 t
이지만 null 종결자는 사용할 수 없습니다. while
루프는 while (dest[i])
이 크기를 초과하여 dest
에 액세스하므로 정의되지 않은 동작을 호출합니다. strncpy()
은 오류가 발생하기 쉽기 때문에 그 의미가 널리 이해되지 않고 버그가 발생하기 쉽습니다. 이 기능을 사용하지 마십시오.
으로는 현재 정의 또는이 char dest[4];
로 정의 된 경우에도 같은 dest
가 역 참조 할 수 없기 때문에 while (dest[i])
가 정의되지 않은 동작을 호출, 위에서 설명했다.
여기 snprintf()
및 strncat()
를 사용하여, 개선 된 버전입니다 :
#include <stdio.h>
#include <string.h>
int main(void) {
char src[] = "santosh";
char dest[5];
*dest = '\0';
strncat(dest, src, 4);
printf("%s\n", dest); // will output "sant"
for (int i = 0; dest[i]; i++) {
printf("%c", dest[i]); // will output "sant" too
}
printf("\n");
snprintf(dest, sizeof dest, "%s", src);
printf("%s\n", dest); // will output "sant"
for (int i = 0; dest[i]; i++) {
printf("%c", dest[i]); // will output "sant" again
}
printf("\n");
for (int i = 0; src[i]; i++) {
printf("%c", src[i]); // will output "santosh"
}
printf("\n");
return 0;
}
'숯불의 최종 도착 [0]'<- 거의 전체 프로그램이이 시점에서 정의되지 않은 동작입니다. 그 선언으로 말하는 것은'dest' 배열은 0 문자의 * 고정 * 크기입니다. 따라서 아무 것도 포함 할 수 없으며 모든 액세스 (읽기 또는 쓰기)가 정의되지 않습니다. –
영국 팝 밴드 ** UB40 **의 이름을 따서 명명되었습니다. 'C++'태그를 제거하는 것도 고려해야합니다. –
정의되지 않은 동작입니다. C는 당신이 원하는 곳 어디에서든지 쓸 수있게 해줄 것이며, 당신이 해야할지를 결정하는 것은 당신에게 달린 것입니다 ... – Charles