2017-01-19 7 views
-1

문자열을 2 가지 방법으로 저장할 수 있습니다. 방법 1 메모리에C/C++에서 문자열, 배열 또는 포인터를 저장하는 데 더 효율적인 방법은 무엇입니까?

char *b="str"; 

사용 메모리가 4 바이트 정도로 문자열 "STR을"기억에서만 사용된다

방법 1 :하여 배열

char a[]="str"; 

방법 2.

방법 2에서 메모리는 '읽기 전용 메모리'에 문자열 "str"을 저장 한 다음 문자열의 첫 번째 문자에 대한 포인터를 저장하는 데 사용됩니다. 따라서 사용 된 메모리는 ROM에 문자열을 저장하기 위해 4 바이트, 그리고 첫 번째 문자에 포인터를 저장하는 데 8 바이트 (64 비트 컴퓨터에서) 여야합니다.

총 1 번째 방법은 4 바이트를 사용하고 방법 2는 12 바이트를 사용합니다. 따라서 방법 1은 C/C++에서 문자열을 저장하는 방법 2보다 항상 좋습니다.

+0

방법 1에서 'a'는 여전히 구문 해석 적 설탕을 사용하여 데이터 "str"에 대한 포인터입니다. –

+0

그리고 왜 'a'가 방법 1의 메모리를 차지하지 않는 걸까요? 당신 의견에'a'가 무엇입니까? – PeterK

+0

컴퓨터 내부에 * "ROM"*이 없습니다 ... – specializt

답변

1

리소스가 제한적인 시스템을 사용하는 경우를 제외하면 포인터가 사용하는 메모리를 너무 신경 쓰지 않아야합니다. 어쨌든 컴파일러를 최적화하면 두 경우 모두 동일한 코드가 생성 될 수 있습니다.

두 번째 경우에는 정의되지 않은 동작에 대해 자세히 알아야합니다.

char a[] = "str"; 

올바르게 "str"을 초기화 비 CONST 문자 배열을 선언한다. 이는 a[0] = 'S';이 완벽하게 허용되며 a"Str"으로 변경 함을 의미합니다.

그러나

char *b = "str"; 

당신은 묵시적으로 const를하는 litteral char 배열에 비 const를 포인터를 선언합니다. 즉, b[0] = 'S';은 litteral 문자열을 수정하려고 시도하고 Undefined Behavior => 문자열을 변경하지 않고도 작업 할 수 있으며, segfault 또는 그 사이의 모든 항목을 의미합니다.

0

인용 한 모든 숫자와 문자열 리터럴이 저장되는 메모리 유형은 플랫폼에 따라 다릅니다.

문자열, 배열 또는 포인터

용어에 대한 일부 학자 인 저장하기위한 더 효율적인 방법입니다

: 포인터는 문자열을 저장할 수 없습니다를; 주소를 저장합니다. 문자열은 항상 배열에 저장되며 포인터는이를 가리킬 수 있습니다. 특히 문자열 리터럴은 정적 저장 기간 배열에 저장됩니다.

방법 1 : 배열 char a[]="str";

이렇게하면 문자열 리터럴의 내용을 자동 저장 기간의 로컬 배열로 만듭니다.

방법 2 : char *b="str";

당신은 표준 C에서 문자열 리터럴 ++에 비 const를 포인터를 결합 할 수 없습니다. 이것은 해당 언어로 잘못 구성되어 있습니다 (C++ 11 이전에는 변환이 단순히 사용되지 않음). 이 변환이 허용되는 C (및 C++의 확장)에서도 포인터가 의도 한 문자열을 수정하려고하는 함수에 포인터를 전달할 수 있기 때문에 매우 위험합니다. Const 정확성은 우발적 인 UB를 컴파일 시간 오류로 대체합니다.

이것을 무시하면 리터럴의 복사본을 만들지 않고 대신 리터럴의 복사본을 가리 킵니다.

방법 1은 C/C++에서 문자열을 저장하는 방법 2보다 항상 좋습니다.

메모리 사용이 중요한 측정 기준은 아닙니다. 방법 1은 문자열을 리터럴에서 자동 배열로 복사해야합니다. 일반적으로 복사본을 만들지 않는 것이 복사본을 만드는 것보다 빠릅니다. 점점 더 긴 문자열로 점점 더 중요 해지고 있습니다.

방법 1과 2의 주요 차이점은 메서드 1의 로컬 배열을 수정할 수 있지만 문자열 리터럴을 수정할 수 없다는 것입니다. 수정할 수있는 버퍼가 필요한 경우 방법 2는 효율성에 관계없이이를 제공하지 않습니다.

0

추가 고려 사항 :

시스템에 RAM 기반의 PC 컴퓨터가 아니라 마이크로 컨트롤러와 같은 진정한 비 휘발성 메모리 (NVM)와 컴퓨터 아니다 가정하자. 문자 리터럴 "str"은 두 경우 모두 NVM에 저장됩니다.

배열의 경우 문자열 리터럴은 NVM에서 런타임에 복사해야하지만 포인터의 경우에는 복사 할 필요가 없습니다. 문자열 리터럴을 바로 가리킬 수 있습니다.

이것은 시스템에서 32 비트라고 가정 할 때 배열 버전은 배열에 대해 4 바이트의 RAM을 차지하며 포인터 버전은 포인터에 대해 4 바이트의 RAM을 차지합니다. 두 경우 모두 문자열 리터럴에 대해 NVM의 4 바이트를 차지해야합니다.

+0

그리고 내 시스템이 64 비트 머신 인 랩톱이면 어레이 버전은 4 바이트의 RAM을 차지할 것이고 포인터는 8 바이트의 RAM을 차지할 것이고 이것들은 NVM의 4 바이트를 차지할 것입니다. 나는 그것을 올바르게 받았 느냐? – user1825567

+0

@ user1825567 아마, C는 'int'가 4 바이트도 아니고 포인터도 8 바이트라는 것을 보장하지는 않습니다. 또한 이러한 컴퓨터에서 8GB RAM을 사용할 수 있다고 가정하면 8 바이트 포인터가 총 RAM의 약 0.000000000097 %를 차지합니다. 이 포인터가 차지하는 저장 공간이 아마도 당신이 걱정할 필요가없는 가장 중요한 것임을 의미합니다. – Lundin

+0

나는 당신의 요지를 얻는다. 그러나 나는 실용적인 해답을 찾지 않고있다. 이론적 인 대답은이 것이 종이에 맞는지 아닌지에 관한 것이다. 그래서 내 자원에 대해 정말로 염려한다면 어떻게해야할까요? – user1825567