programing

다른 문자열 리터럴에 대한 두 문자 포인터의 주소가 동일합니다.

minecode 2022. 8. 18. 23:05
반응형

다른 문자열 리터럴에 대한 두 문자 포인터의 주소가 동일합니다.

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

int main()
{
    char * p = "abc";
    char * p1 = "abc";
    printf("%d %d", p, p1);
}

두 포인터의 값을 인쇄하면 동일한 주소가 인쇄됩니다. 왜일까요?

같은 내용을 가진 2개의 다른 문자열 리터럴을 같은 메모리 위치에 배치할지, 아니면 다른 메모리 위치에 배치할지 여부는 구현에 따라 달라집니다.

당신은 항상항상 치료해야 한다를 다루어야 한다.p ★★★★★★★★★★★★★★★★★」p1수 있거나, 같은 주소로 지적하지 못할지 모르지만 두개의 다른 포인터(심지어 그들은 같은 내용을 가지고 있).같은 주소를 가리킬 수도 있고 가리킬 수도 없는 두 개의 서로 다른 포인터(같은 내용을 가지고 있어도)로 사용됩니다.당신은 컴파일러 최적화에 의존하지 말아야 한다.컴파일러 최적화에 의존해서는안 됩니다.

C11 표준, 6.4.5, 문자열 리터럴, 의미론

요소의 값이 적절한 경우 이들 배열이 구별되는지 여부는 지정되지 않았습니다.프로그램이 이러한 배열을 수정하려고 하면 동작은 정의되지 않습니다.


인쇄의 형식이 되어야 한다인쇄형식은다음과 같아야 합니다.%p:

  printf("%p %p", (void*)p, (void*)p1);

이유에 대해서는, 이 답을 참조해 주세요.

당신의 컴파일러는 두 리터럴이 같은 것을 탐지하는 데 매우 똑똑한 것 같습니다.그리고 리터럴이 일정하기 때문에 컴파일러는 리터럴을 두 번 저장하지 않기로 결정했습니다.

이것이 반드시 그럴 필요는 없다는 것을 언급할 가치가 있어 보인다.에 대한 Blue Moon의 답변보시기 바랍니다.


그것:그것:더printf()차 진술this스테이트먼트는다음과같아야 합니다처럼 보여야 한다.

printf("%p %p", (void *) p, (void *) p1);

~하듯이로"%p"포인터 값 및 다른 것 인쇄하는 형식의 포인터에값을인쇄하는데 사용되어야 하며,정의되어야 한다 대해타입의 포인터에 포인터 정의된다 사용될 수 있어야 한다.void *한정되어 있습니다.*1


또한 나는 코드는그리고 코드가 빠져있네요를 그리워하라고 말하고 싶습니다.return성명지만 C표준으로 대체되는 과정에 있는 것 같아C규격이 변경되고 있는것 같습니다.다른 사람들은 친절하게 이 명확하게 할 수 있다.다른 사람들은 이것에 대해 해명할 수 있다.


투 *1: 캐스팅 투 ★★★★★★★★★★★★★★★★★★★★」void *까지는 없다char *하다

컴파일러가 "문자열 풀링"이라고 불리는 작업을 수행했습니다.두 포인터가 같은 문자열 리터럴을 가리키도록 지정했기 때문에 리터럴의 복사본이 하나만 생성되었습니다.

기술적으로는:포인터를 "계속"하지 않았다고 불평했어야 했다.

const char* p = "abc";

이는 Visual Studio를 사용하고 있거나 -Wall이 없는 GCC를 사용하고 있기 때문일 수 있습니다.

명시적으로 메모리에 2회 보존하는 경우는, 다음의 조작을 실시해 주세요.

char s1[] = "abc";
char s2[] = "abc";

여기서는 문자에 대한 포인터가2개가 아니라2개의 c-string 문자 배열이 필요함을 명시적으로 나타냅니다.

주의: 문자열 풀링은 컴파일러/옵티마이저 기능으로 언어의 한 부분이 아닙니다.다른 환경에서 이러한 다양한 컴파일러는 최적화 수준, 컴파일러 플래그 및 문자열이 다른 컴파일 유닛에 있는지 여부에 따라 다른 동작을 생성합니다.

다른 사람들이 말했듯이 컴파일러는 같은 값을 가진 것을 알아차리고 최종 실행 파일에서 데이터를 공유하도록 결정합니다.하지만 좀 더 고급스러워지죠. 제가 다음 사항을 컴파일할 때gcc -O

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

int main()
{
  char * p = "abcdef";
  char * p1 = "def";
  printf("%d %d", p, p1);
}

인쇄하다4195780 4195783나를 위해.그것은,p13바이트 후에 시작합니다.p그래서 GCC는 일반적인 서픽스를 확인했습니다.def(포함)\0터미네이터)와 같은 최적화를 실시합니다.

(댓글이 되기에는 너무 길기 때문에 답변입니다.)

코드의 문자열 리터럴은 코드의 읽기 전용 데이터 세그먼트에 저장됩니다."abc"와 같은 문자열 리터럴을 적어두면 실제로는 "const char*"가 반환되며 모든 컴파일러 경고가 있을 경우 해당 시점에서 캐스팅 중임을 알 수 있습니다.당신이 이 질문에서 지적한 바로 그 이유 때문에 당신은 그 조건들을 변경할 수 없습니다.

문자열 리터럴("abc")을 작성하면 해당 문자열 리터럴을 포함하는 메모리에 저장되고 동일한 문자열 리터럴을 참조할 경우 재사용됩니다. 따라서 두 포인터는 "abc" 문자열 리터럴이 저장되어 있는 동일한 위치를 가리킵니다.

제가 예전에 배워서 설명을 잘 못 했을 수도 있어요, 죄송해요.

이것은 실제로 사용하고 있는 컴파일러에 따라 다릅니다.

TC++ 3.5를 사용하는 시스템에서는 두 포인터에 대해개의 서로 다른 값, 즉 두 의 서로 다른 주소를 출력합니다.

컴파일러는 메모리 내의 값의 존재를 체크하고, 그 존재에 따라 같은 값이 참조될 경우 이전에 저장된 값과 동일한 참조를 재할당하거나 사용합니다.

컴파일러가 코드를 해석하는 방법에 따라 다르므로 너무 생각하지 마십시오.

그게 다야...

문자열 자체가 메모리 내의 주소이기 때문입니다.다시 "filename"이라고 쓰면 동일한 주소가 저장됩니다.

컴파일러 최적화입니다만, 휴대성을 위해서 최적화를 실시하지 말아 주세요.컴파일된 코드가 실제 코드보다 읽기 쉬운 경우가 있습니다.

문자열 리터럴을 사용하고 있습니다.

컴파일러가 같은 문자열 리터럴 두 개를 잡으면

동일한 메모리 위치를 제공하므로 동일한 포인터 위치를 표시합니다./

언급URL : https://stackoverflow.com/questions/19088153/addresses-of-two-char-pointers-to-different-string-literals-are-same

반응형