your programing

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

lovepro 2020. 10. 7. 08:02
반응형

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


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

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

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


동일한 내용을 가진 두 개의 다른 문자열 리터럴이 동일한 메모리 위치에 배치되는지 또는 다른 메모리 위치에 배치되는지는 구현에 따라 다릅니다.

동일한 주소를 가리킬 수도 있고 가리 키지 않을 수도 있으므로 항상 pp1두 개의 다른 포인터 (컨텐츠가 같더라도)로 취급해야 합니다. 컴파일러 최적화에 의존해서는 안됩니다.

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

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


인쇄 형식은 다음 %p같아야합니다 .

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

이유는 이 답변참조하십시오 .


컴파일러는 매우 영리 해 보이며 두 리터럴이 동일하다는 것을 감지합니다. 그리고 리터럴이 일정하기 때문에 컴파일러는 두 번 저장하지 않기로 결정했습니다.

이것이 반드시 그럴 필요는 없다는 것을 언급 할 가치가있는 것 같습니다. 참조하시기 바랍니다 블루 문 '의 이에 대한 대답을 .


Btw : printf()문장은 다음과 같아야합니다.

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

같은 "%p"포인터 값을 출력하기 위해 사용되어야하며, 이는 타입 포인터 정의 void *만. *1


또한 코드가 return문장을 놓쳤다 고 말하고 싶지만 C 표준이 변경되는 과정에있는 것 같습니다. 다른 사람들은 이것을 친절하게 설명 할 수 있습니다.


* 1 : 포인터에는 void *여기로 캐스팅 할 필요가 없지만 char *다른 모든 유형에 대한 포인터에는 캐스팅 이 필요하지 않습니다 .


여러분의 컴파일러는 "문자열 풀링"이라는 것을 수행했습니다. 동일한 문자열 리터럴을 가리키는 두 개의 포인터를 원한다고 지정 했으므로 리터럴의 복사본을 하나만 만들었습니다.

기술적으로 : 포인터를 "const"로 만들지 않았다고 불평했을 것입니다.

const char* p = "abc";

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

명시 적으로 메모리에 두 번 저장하려면 다음을 시도하십시오.

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

여기서는 문자에 대한 두 개의 포인터가 아닌 두 개의 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나를 위해 인쇄 합니다. 즉, p1에서 3 바이트를 시작 p하므로 GCC는 def( \0종결자를 포함하여 ) 의 공통 접미사를 확인 하고 표시된 것과 유사한 최적화를 수행했습니다.

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


String literals in the code are stored in a read-only data segment of the code. When you write down a string literal like "abc" it actually returns a 'const char*' and if you had all the compiler warnings on it would tell you that you are casting at that point. You are not allowed to alter those strings for the very reason you have pointed out in this question.


When you create a string literal ("abc"), it is saved into a memory, which contains string literals, and then it's being reused if you refer to the same string literal, thus both pointers pointing to the same location, where the "abc" string literal is stored.

I've learned this some time ago so I might not have explained it really clearly, sorry.


This actually depends on which compiler you are using.

In my system with TC++ 3.5 it prints two different values for the two pointers i.e. two different addresses.

Your compiler is designed s.t it will check for existence of any value in the memory and depending on its existence it will reassign or use the same reference of the previously stored value if the same value is referred to.

So don't think about it too much as it depends on the way the compiler parses the code.

THAT'S ALL...


because string "abc" itself a address in memory. when u write "abc" again it store same address


It is compiler optimization but forget optimization for portability. Sometime compiled codes are more readable than actual codes.


you are use string literal,

when complier catch two same string literal,

it give the same memory location, therefore it show same pointer location./

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

반응형