문자열을 포인터와 배열에 대입할때 각각 어떻게 되나요?

""로 문자들을 감싸면 문자열이 됩니다

그리고 그 문자열들을 정적배열에 대입할때는

const char Hello[6] = "World";

다음과 같이 대입해서 사용합니다 그리고 마지막 NULL문자를 위해서 메모리를 하나 더 잡습니다

그리고 동적배열에 대입할때는

const char* pHello = new char[6];
pHello = "World";

delete pHello;

다음과 같이 합니다

그런데 제가 실수로 한번은

const char* pHello = "World";

다음과 같이 pHello에게 new로 "World"가 저장될 메모리를 동적할당 하지 않고

그냥 대입을 해버렸습니다

그래서 수정을 하려고 했는데 이미 컴파일을 눌러버려서 '아 오류뜨겠다’라고 생각했습니다

그런데 컴파일이 성공하고 아무런 문제도 일어나지 않았습니다

그래서 좀 당황했습니다 저렇게 사용할수 있다는 것을 한번도 공부한적이 없는데

왜 저게 가능한 건가요 "단순히 버그"인가요? 물론 그건 아닌거 같습니다…

아니면 컴파일러가 "아 사용자 이녀석 메모리를 할당 않하고 그냥 대입했네 그럼 내가 메모리를 생성해서 대입해 주어야 겠네"라고 생각해서 대신 메모리를 만들어다가 저 "World"를 메모리에 넣고 그 메모리의 시작 주소를 pHello에게 대입해 주는건가요?

계속 생각하고 검색해 봤는데 저게 가능한 이유는 나오지 않고

그냥 저렇게도 사용할수 있다고 하는 글밖에 없어서 질문을 올리게 되었습니다

2 Likes

"World"는 변하지 않는 문자열이에요. 따라서 "World"는 컴파일 시 자동으로 할당되어서 프로그램 안에 저장된다고 보시면 되요. 우리가 int a = 1; 이라고 선언했을 때 1을 담기 위해서 따로 할당을 해주지 않는 것처럼요. 그리고 문자열이기 때문에 배열처럼 포인터 변수로 주솟값을 저장해서 사용할 수 있는거구요.

그리고 동적배열에 대입하는건 좀 잘못하신 것 같아요. 문자열이 ‘=’ 오른쪽에 올 때는 그 문자열의 주솟값을 의미하거든요. 그래서 new char[6]으로 할당한 배열에 들어간 것이 아니라 pHello에 “World” 문자열의 포인터 값을 집어넣은 것이 되요. 그리고 const로 선언하셨기 때문에 "World"의 주소값도 저장되지 않을 것 같아요.

틀린 부분 있으면 말씀해 주세요~~

안녕하세요.

둘다 문법상 사용할 수 있는 방법이고요.
어떻게 사용하게되든 static 영역에 World라는 문자열이 위치하게 됩니다.

그 문자열 데이터를 사용해서 프로그램이 동작하는것이므로 상관이없는 것이죠.

#include <stdio.h>

int main()
{
    const char* pHello = "World";

    printf("%s", pHello);
}
main:                                   # @main
        push    rax
        mov     edi, .L.str.1
        mov     esi, .L.str
        xor     eax, eax
        call    printf
        xor     eax, eax
        pop     rcx
        ret

.L.str:
        .asciz  "World"

.L.str.1:
        .asciz  "%s"
#include <stdio.h>

int main()
{
    char pHello[] = "Worlddafdsfasfs";

    printf("%s", pHello);
}

main:                                   # @main
        sub     rsp, 24
        movaps  xmm0, xmmword ptr [rip + .L_ZZ4mainE6pHello]
        movaps  xmmword ptr [rsp], xmm0
        lea     rsi, [rsp]
        mov     edi, .L.str
        xor     eax, eax
        call    printf
        xor     eax, eax
        add     rsp, 24
        ret

.L_ZZ4mainE6pHello:
        .asciz  "Worlddafdsfasfs"

.L.str:
        .asciz  "%s"

뭐 물론 최적화 때문에 좀 길게 해서 보여드렸는데
하고싶은 말은 뭐냐면 어쩌피 문자열은 프로그램에 존재한다 이겁니다.

1 Like

문자열 복사하는 방법을 한번 다시 생각해보세요.

char a[] = "World";

이거는 initialize와 assign의 차이를 모르셔서 그런거 같은데 한번 아래 링크를 읽어보세요.

1 Like

감사합니다 지금까지 잘못 알고 있었네요 ㅎㅎ

그리고 죄송합니다 추가로 질문하고 싶은게 있는데요

"Hello"

다음과 같이 할때 Hello라는 문자열이 프로그램에 존재한다고 하셨는데

저 Hello라는 문자열이 메모리에 저장되는 건 컴파일러가 컴파일 타임에 하나요?

아니면 런타임때 저 문자열을 보면 그때 메모리에 저장해서 사용할수 있게 하나요?

컴파일러가 컴파일을 할때 데이터가 들어갑니다.
그렇기 때문에 exe파일안에 데이터가 있는것이죠.

그래서 그 파일을 실행하면 메모리에 올라가서 작동하는겁니다.

그렇군요 알려주셔서 감사합니다

const char Hello[6] = "World";
참고로 이거 특수 문법임 원래 안 되는건데 스트링 리터럴에 대해서만 허용해주는 거임 C 표준 찾아보셈

3 Likes

그렇군요 감사합니다