[C] 메모리 동적할당은 포인터의 메모리한테만 할당할수있는건가요?

조회수 543회
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    char *pszData;
    char first[20], second[20];

    gets_s(first, sizeof(first));

    pszData = (char*)malloc(sizeof(first));
    strcpy_s(pszData, sizeof(first), first);

    puts(pszData);

    gets_s(second, sizeof(second));

    pszData = (char*)realloc(pszData, sizeof(first)+sizeof(second));
    strcpy_s(pszData, sizeof(first), first);
    strcat(pszData, second);

    puts(pszData);

    free(pszData);
    return 0;
}

안녕하세요!! 제가 동적할당을 공부하고 있는데요!

책으로 공부하면서 예문으로 나온 문제를 풀면서 궁금한점이 있어서 질문합니다!

[문제]

사용자로부터 입력받은 첫 번째 문자열을 동적 할당된 메모리에 저장한 후 화면에 출력하고, 두 번째로 입력받은 문자열을 첫 번째로 동적 할당된 메모리에 덧붙여 출력하는 프로그램을 작성합니다. 이때, 메모리가 부족해서 문제가 발생하지 않도록 메모리의 크기를 조정합니다. 기존에 할당받은 메모리의 크기를 늘려도 좋고 다시 할당받아도 좋습니다. 혹은 두 경우를 모두 구현하는 것도 좋습니다.

이 코드는 다른분이 올리신 답안인데요.

동적할당이라는게 변수가 얼만큼의 메모리가 필요할지 모르기도하고 무턱대고 큰 메모리를 처음부터 주는게 아니라 필요한 만큼만 나중에 주는 거잔아요? 저는 이 코드에서 그런 용도로 쓰려면

char first[20], second[20];

이 부분도 처음부터 큰 메모리(20)를 넉넉하게 줄게 아니라 나중에 동적할당하는게 맞다고 생각하는데 지금까지 참고한 코드들은 동적할당을 포인터에게만 주더라구요...

pszData = (char*)malloc(sizeof(first));

배열을 동적할당하려면 어떻게 해야되는건가요? 꼭 이렇게 해야만 하는건가요? 제가 원하는걸 구현할수 있다면 어떻게 하는지 답변 부탁드립니다!!

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 사용자의 입력 길이가 얼마가 될지 프로그램은 알수가 없어서, 사용자 입력을 그대로 동적할당으로 받지 못합니다. 그래서 넉넉하게 배열을 선언해 놓고 그곳에 받거나, 애초에 길이의 한계를 알려주어서 사용자가 그 길이 이상을 입력하면 잘라서 사용하거나 에러 표시, 또는 재입력하도록 하시면 됩니다. 알 수 없는 사용자 2020.9.14 18:07

2 답변

  • int main(){
        char *pt2;
        char *pt;
        char a[10];
        char c[10];
        pt = (char *)malloc(sizeof(char) * 0x20);
        pt2 = (char *)malloc(sizeof(char) * 0x20);
        printf("%p\n", c);
        printf("%p\n", a);
        printf("%p\n", &pt);
        printf("%p\n", &pt2);
        for (int i=0; i<20; i++)
        {
            printf("%p ", &pt[i]);
        }
        printf("\n");
        for (int i=0; i<20; i++)
        {
            printf("%p ", &pt2[i]);
        }
        return 0;
    }
    //stack
    //c: 0x7ffdb8eb4b84  10
    //a: 0x7ffdb8eb4b8e  10
    //pt: 0x7ffdb8eb4b70  8
    //pt2 : 0x7ffdb8eb4b78  8 
    //heap
    //a chunk
    //0x16dec20 0x16dec21 0x16dec22 0x16dec23 0x16dec24 0x16dec25 0x16dec26 0x16dec27 0x16dec28 0x16dec29 0x16dec2a 0x16dec2b 0x16dec2c 0x16dec2d 0x16dec2e 0x16dec2f 0x16dec30 0x16dec31 0x16dec32 0x16dec33 
    //b chunk
    //0x16dec50 0x16dec51 0x16dec52 0x16dec53 0x16dec54 0x16dec55 0x16dec56 0x16dec57 0x16dec58 0x16dec59 0x16dec5a 0x16dec5b 0x16dec5c 0x16dec5d 0x16dec5e 0x16dec5f 0x16dec60 0x16dec61 0x16dec62 0x16dec63 
    

    0x20크기로 만들었다고 가정하겠습니다. 만약에 a chunk에 0x40크기가 들어오면 b chunk 에 영향이갑니다. (overflow)

    만약에 0x20크기에 0x10크기가 들어가서 a chunk를 강제로 줄이면 b chunk에서 가지고 있는 a chunk에 대한 정보는 잘못된 값이 됩니다. 그리고 a chunk 쪽에서 잘못된 값을 넣어서 b chunk 에서 a chunk 정보를 보고 있는 포인터쪽에 악의적인 주소값을 넣을 경우 취약요소가 됩니다.

    그러기 때문에 구조적으로 할당된 공간에 대해서는 자동적으로 변경이 불가능하니 재할당이 필요하며....

    예시답안에서 문제에서 제공되어 있지 않는 전재(20글자 이하)를 반영한것처럼... 전재가 변경되어야합니다....

    • 나중에 재할당을 해서 발생할수있는 취약요소를 만들지 않게 길이 20같이 미리 사이즈를 정하는게 좋다는...거죠? 이렇게 이해하면 되는건가요? 말이 저한텐 아직 어려워서 ㅠㅠ 알 수 없는 사용자 2020.9.16 16:28
    • 구조적으로 고무줄처럼 할당할수가 없다고 말씀드리는거예요... 그래서 동적할당할 크기를 사전에 입력받을 필요가 있다는 말씀입니다. 애초에 질문이 힙공간에 대한 구조적인 질문이라 그에 대한 답변 드렸고.. 관련되어 참고할만 정보또한 드렸으니 공부하시는게 좋을거 같아요 제 답변이 전부라고 생각하지 마시고... 김호원 2020.9.16 16:33
    • 답변감사합니다!! :) 알 수 없는 사용자 2020.9.16 16:36
    1. malloc 함수의 return 값은 주소값이기 때문에 포인터 변수에 지정하는게 맞습니다( malloc 함수 참고 )

    2. 큰 메모리에 대한 정확한 근거가 없어보입니다. 동적할당으로 20사이즈 할당시에 정적인 공간에 20 공간보다 더 많이 메모리를 차지할 수 있습니다.....그리고 문제자체에서 최초 입력값에 대한 사이즈에 대한 언급이 문제에 없습니다. 질문하신분이 원하시는 대답을 얻으려면 문제에 사전에 "몇 글자 입력 받는지에 대해 물어본다" 라는 전재가 필요해보입니다.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        char *pt;
        pt = (char *)malloc(sizeof(char) * 20);
        pt[0] = 'h';
        pt[1] = 'i';
    
        int *pt2;
        pt2 = (int *)malloc(sizeof(int) * 20);
    
        pt2[1] = 12345678;
    
        printf("%c\n", pt[1]); // 'i'
        printf("%d\n", pt2[1]); // 12345678
    
        return 0;
    }
    // *pt 의 사이즈와 char a[20] 사이즈는 다르다.
    // 관련되어서는 fastbin 구조..
    
    • 답변 감사합니다! 음.. 혹시 질문으로 드렸던 코드에서 배열을 선언할때 크기를 정하지 않고 그 크기를 동적할당으로 받을수는 없을까요? 20크기로 만들었는데 들어오는 값의 크기가 10일때 불필요하게 낭비되는 메모리를 만들고 싶지 않아서요!! 알 수 없는 사용자 2020.9.14 16:41

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)