2014-04-27 2 views
0

저는 C에서 완전한 멍청한 놈입니다. 코드의 특정 부분이 올바르게 컴파일되는 이유를 이해하는 데 도움이 필요합니다. 왜 컴파일 오류입니까?

main(){ 
    char name[3]; 
    strcpy(name, "12345678912312"); 
    printf("%s\n",name); 
} 

그래서이 코드는 제대로 컴파일, 그것은 세그먼트 오류가 발생하지 않는 이유 그러나 내가 이해가 안 돼요. 내 이해 c에서 각 문자는 1 바이트입니다. 배열 이름은 3 바이트를 유지할 수 있다고 가정합니다. 대신에 그 이상을 저장할 수 있습니다. 왜 그런가요?

또한이 문자를 하나 더 추가하면 불법 명령어 (코어 덤프)가 발생합니다.

main(){ 
    char name[3]; 
    strcpy(name, "123456789123121"); 
    printf("%s\n",name); 
} 

그런 다음 코드에 다른 문자를 추가하면 세그먼트 오류 (코어 덤프) 오류가 발생합니다. 왜 오류가 다른가요? 그리고 왜 그들은 전에 일어나지 않았습니까?

마지막으로 각 기능에 대한 문서는 어디에서 찾을 수 있습니까? 내가 자바 문서를 참조하는 데 사용되는 자바에서 오는거야.

우분투 리눅스에서 GCC 컴파일러를 사용하고 있습니다.

답변

1

할당되지 않은 메모리 위치에 쓰고 있기 때문에 두 코드 모두 정의되지 않은 동작을 호출합니다. 이 경우에는 어떤 일이 일어날 수 있습니다. 프로그램이 실행되고 예상 출력을 제공하거나 제공하지 않을 수 있으며 충돌이 발생하거나 세그먼트 오류가 발생합니다.
또한 strcpy은 배열 바운드를 검사하지 않으며 컴파일러는 경고/오류를 발생시키지 않습니다.

+0

그런 경우에는 name 변수에 메모리를 할당해야합니까? 이것이 해결책이라면 어떻게 구현할 것인가? –

+1

당신은'name'이 당신이 붙여 넣기하고있는 문자열의 크기보다 더 큰 크기 (null로 끝나는 문자열 문자에 대해 하나의 여분의 문자가 필요함)를 가지고 있는지 확인해야합니다. – vsoftco

+1

당신의 특별한 문제는'const char * name = "123456789123121"'을 사용하십시오. 일반적인 동적 메모리 할당을 위해서는'malloc'을 찾아보십시오. – IllusiveBrian

1

여기에서 몇 가지 질문을 읽으면 "정의되지 않은 동작"(종종 UB로 약칭 됨)에 대해 많이 알게 될 것입니다.

귀하의 프로그램이 C 표준 외부의 어떤 것을 수행하는 경우 표준은 어떤 일이 발생할지 정의하지 않는다는 것을 의미합니다. 아무거나 일어날 수있다.

배열의 끝을 넘어서 쓰는 것이 UB를 트리거 할 수있는 한 가지 예입니다.

C는 배열 바운드 검사를 수행하지 않으므로 배열 끝을 넘어 서면 컴파일러가 배열을 구현하는 방법, 배열을 메모리에 배열하는 방법 및 그 뒤에 오는 결과에 따라 결과가 달라집니다. 그러나 요점은 특정 행동에 의존 할 수 없다는 것입니다.

C 및 C++에 대한 내가 가장 좋아하는 참조 사이트는 cppreference입니다. 하지만 리눅스에서는 사람과 함께 라이브러리 함수의 정의를 읽을 수도 있습니다 (예 : man strcpy.

+0

UB와 배열 바운드 검사 및 그 처리 방법을 설명해 주셔서 감사합니다. 이제는 조금 더 이해할 것 같아서 strcpy 함수를 자세히 살펴 보겠습니다. 감사 :) –

관련 문제