2017-05-10 6 views
3

안녕하세요, 저는 최근에 C 프로그래밍을 선택했고 포인터를 이해하려고했습니다. 늘어나는만큼 포인터에 값을 저장하려면 malloc을 사용하여 저장할 값의 크기를 바인드해야합니다. 내가 11 바이트 크기의 문자열을 저장하기 위해 11 바이트의 메모리를 할당하지 않았기 때문에 다음 코드는 작동하지 않아야한다.하지만 내 이해를 넘어서는 몇 가지 이유 때문에 완벽하게 작동한다.문자열에 대한 메모리를 바인드하지 않고이 작업이 필요한 이유를 알고 싶습니다.

str = "hello world\0"; 

str"hello world\0" 포인트로 초기화 chars 어레이의 첫 번째 요소의 주소 이때

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

int main(){ 

    char *str = NULL; 

    str = "hello world\0"; 
    printf("filename = %s\n", str); 
    return 0; 
} 
+3

끝에 '\ 0'을 넣지 않아도됩니다. 문자열 리터럴은 그렇게합니다. – InternetAussie

답변

1

C 프로그램에서 문자열 리터럴을 선언하면 프로그램 코드의 read-only section에 저장됩니다. 명령문 char *str = "hello";char* 포인터에이 문자열의 주소를 할당합니다. 그러나 문자열 자체 (문자 h, e, l, lo\0 문자열 터미네이터 포함)은 여전히 ​​읽기 전용 메모리에 있으므로 문자를 전혀 변경할 수 없습니다.

문자열 선언에 0 바이트 터미네이터를 명시 적으로 추가 할 필요가 없습니다. C 컴파일러가이 작업을 수행합니다.

3

. 즉, str은 "문자열 리터럴"을 가리 킵니다.

정의에 따르면 배열은 할당되며 첫 번째 요소의 주소는 "유효"해야합니다.

인용 C11 챕터 §6.4.5, 문자열 리터럴 번역 단계 7

, 값 0의 바이트 또는 코드가 문자 스트링에서 결과 나 각 멀티 문자 시퀀스에 추가되고 리터럴. 78) 멀티 바이트 문자 시퀀스를 사용하여 시퀀스를 포함하기에 충분한 정적 저장 기간 및 길이의 배열을 초기화합니다. 문자열 리터럴의 경우 배열 요소는 char 유형이며 멀티 바이트 문자 시퀀스의 개별 바이트로 초기화됩니다. [...]

메모리 할당 은 여전히 ​​는 (메모리 할당 기능을 통해) 단지 하지 명시 적으로 당신에 의해 발생합니다. 상기 기본적으로 배열 널 종료 할 것이다 (인용의 제 문) 한 바와 같이, 단부에서 상기


상기 "...\0"은 반복적이다.

1

오른쪽. 그러나이 경우에는 상수 메모리 영역에 배치 된 문자열 리터럴을 가리키고 있습니다. 포인터가 스택 영역에 만들어집니다. 그래서 당신은 다른 주소를 가리키고 있습니다. 즉, 문자열 리터럴의 시작 주소에서.

포인터 변수에 문자열 리터럴을 복사 해보십시오. 그런 다음 메모리를 할당하지 않았기 때문에 오류가 발생합니다. 지금 당신이 이해하기를 바랍니다.

2

malloc없이 char 변수를 사용하면 할당하려는 문자열이 읽기 전용임을 나타냅니다. 즉, 문자열 상수에 대한 포인터를 만드는 중입니다. "hello world\0"은 메모리의 읽기 전용 부분에 있으며 여러분은 그것을 가리키고 있습니다.

이제 문자열을 변경하려고합니다. hH으로 변경하면 str[0]='H'이됩니다. Without malloc 없이는 만들 수 없습니다.

0

문자열 리터럴 용 저장소는 프로그램 시작시 따로 보관되어 프로그램이 종료 될 때까지 보관됩니다. 이 저장소 일 수 있으며 읽기 전용이며 문자열 리터럴의 내용을 수정하려고하면 정의되지 않은 동작이 발생합니다 (작동 할 수도 있고 충돌 할 수도 있습니다).