2011-08-16 3 views
6

이 질문에서 응답에 따라 질문 : 지금의 차이를 이해char 배열 VS 숯불 *

const char myVar* vs. const char myVar[]

const char* x = "Hello World!"; 
const char x[] = "Hello World!"; 

,하지만 내 새로운 질문은 다음과 같습니다

(1) 무엇 x를 재 할당하면 첫 줄에 "Hello World"문자열이 생깁니 까? 그 시점까지는 아무 것도 가리 키지 않을 것입니다. 범위가 끝났을 때 파괴 될까요?

(2) 두 예제의 값은 컴파일러가 메모리에 어떻게 다르게 저장합니까?

답변

9

코드에 "Hello World!"을 삽입하면 컴파일러에서 해당 문자열을 컴파일 된 실행 파일에 포함시킵니다. 프로그램이 실행될 때 그 문자열은 main에 대한 호출 전에 메모리에 생성되고, 심지어는 어셈블리 호출 전에 __start (정적 초기화 프로그램이 실행되기 시작하기 전)이라고 믿어 의심치 않습니다. char * x의 내용은 new 또는 malloc을 사용하거나 main의 스택 프레임에 할당되지 않으므로 할당 할 수 없습니다.

그러나 함수 또는 메서드 내에서 선언 된 char x[20] = "Hello World"은 스택에 할당되며 범위 내에 실제로는 두 개의 복사본이 있습니다. 즉, 실행 파일이 미리로드 된 스택과 스택에 하나의 스택이 있습니다. 할당 된 버퍼.

+0

const char x []는 데이터를 스택으로 복사한다고 가정합니다. –

-1
  1. 정식 두 경우 "Hello World!" 문자열 char 연속 한 정적 메모리에 할당되고, 그래서없이 동적으로 할당 된 메모리 되찾기이나 파괴하는 임의의 클래스 인스턴스가있다;
  2. x은 정의 된 위치에 따라 정적 메모리 또는 스택에 할당됩니다. 그러나 해당 "Hello World!" 문자열을 가리 키도록 포인터가 초기화되지만 배열은 문자열 리터럴을 직접 문자열에 복사하여 초기화됩니다.

이론적으로 컴파일러는 문자열 리터럴에 액세스 할 수있는 방법이 없을 때 두 문자열 리터럴의 메모리를 자유롭게 사용할 수 있습니다. 실제로 정적 메모리는 종료 될 때까지 프로그램에 할당 된 채로 남아 있기 때문에 첫 번째 메모리는 재생 될 수 없습니다. 반면에 배열이 스택에 할당되면 컴파일러는 배열이 제대로 초기화되었는지 확인하기 위해 다른 방법을 사용할 수 있으며 어레이 메모리는 꺼질 때 다시 회수됩니다. 범위.

+0

이 외에도 포인터로 sizeof (x)를 사용하면 4 (또는 64 비트 코드에서 8)가되고 배열과 sizeof (x)는 배열에 포함 된 바이트 수가됩니다. – Matthew

+2

-1 : 동일한 방식으로 할당되지 않습니다. 첫 번째 예제는 정적 메모리에 대한 포인터입니다. 두 번째 예제는 내용이''Hello world! ''로 초기화되는 비 정적 배열입니다. –

+2

const char x [] 뒤에있는 생각은 배열이 단순히 포인터가 아니라 스택에 있다는 것입니다. "Hello World!" 그것에 복사됩니다.이것은 최적화 된 상태 일지 모르지만 그 생각은 단순한 포인터와는 완전히 다릅니다. –

4

컴파일러는 첫 번째를 RODATA (읽기 전용 데이터)라는 메모리 섹션에 저장합니다. 프로그램이 계속 실행되는 동안 메모리는 여전히 초기 값을 유지합니다.

둘째 줄은 다른 배열과 마찬가지로 스택에 저장됩니다. 다른 지역 변수와 마찬가지로 범위가 끝나면 덮어 쓸 수 있습니다.

+0

'프로그램이 아직 실행 중이라면 메모리는 여전히 초기 값을 유지합니다. '즉, 문자열의 범위는 프로그램 범위가 아니라 함수의 범위입니다. –