• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

동적할당에 관한 질문입니다.

21.08.18 13:25 작성 조회수 131

0

이 챕터에서 질문하기에는 좀 그런거일수도 있는데...

이부분을 배웠는지 기억이 안나서요

예를들자면

강의에서의 예제를 기준으로

struct flex* pf = (struct flex*)malloc(sizeof(struct flex) + n * sizeof(double));

n 이 3일때 flexible array 의 크기를 double 형 값을

최대 3개까지 저장가능한 크기로 할당하는건데...

왜 4개 이상의 값을 넣어도 전혀 에러가 발생하지 않고

오히려 잘 작동하는지가 궁금하네요...

주소값도 8byte 간격으로 잘 나오고요.

이러면 메모리를 할당하는 의미가 없는거 아닌가요??

제가 뭘 잘못 알고있는지 궁금합니다.

위의 구조체 말고 일반적인 동적할당에서도 똑같네요.

아 그리고 궁금한게 한가지 더있는데

구조체 변수의 주소와 구조체의 첫번째 주소값은 같잖아요

struct flex

{

size_t count;

double value[]

}

여기에서 

struct flex* pf = (struct flex*)malloc(sizeof(struct flex) + n * sizeof(double));

이렇게 했을때

pf 값과 &pf->count 의 값이 똑같은데

왜 *pf 의 값은 pf->count 의 값이 아니라 다른 이상한 값이

나오는지가 궁금합니다.

답변 1

답변을 작성해보세요.

1

안소님의 프로필

안소

2021.08.19

안녕하세요!

1. 왜 에러가 안나는지, 그럼에도 불구하고 크기로 동적할당을 왜 해주는지는  https://stackoverflow.com/questions/4534780/writing-to-pointer-out-of-bounds-after-malloc-not-causing-error 이 링크 읽어보시면 이해에 도움이 되실 것 같아요! 동작은 가능하며 문제 없는 것처럼 보이나 동적할당 받은 범위를 벗어난 곳까지 접근하는 것은 위험하다고 말하고 있어요. 세그폴트와 여러 메모리 문제를 일으킬 수 있다고 말하고 있습니다. 

동작은 됩니다. 어차피 동적할당 받고 그 시작 주소 결과를 포인터에다가 받는 것일 뿐이라 그 포인터로 연산 하는건 자유니까 (ptr[3] 이런것도 사실 *(ptr + 3) 이런 산술 연산의 결과와 같습니다.) 동작 자체는 가능합니다. 게다가 힙은 스택과 다르게 프로그래머가 자유롭게 쓸 수 있는 메모리 공간이니까요! 그런데 동적할당 해제(free)를 하려고 하면 어떨까요! 해제시킬 때 free 에 보통 포인터만 넘겨주는데 (free ptr; 이런식) 이는 해당 주소에 얼마만큼의 동적할당 크기를 받았었는지를 시스템 내부적으로 기억하고 있기 때문입니다. 그래서 free 에 주소만 넘겨주면 해당 크기만큼 알아서 해제해주는거에요. 근데 이전에 동적할당 받았던 범위의 이외 부분까지 접근하여 사용했었다면 당연히 이 부분은 해제에서 제외가 되고 메모리 누수가 되겠죠! 

2. *pf 가 count 와 같다는게 말이 되려면 pf 는 구조체가 아니라 int 여야 하는게 아닐까요..? 간접참조의 원리는.. 그 시작주소에서부터 그 자료형의 크기까지의 메모리를 참조하는 것입니다. 즉, int * ptr 인 ptr 을 간접참조하여 *ptr 을 한다면, 이건 int 를 가리키는 포인터이기에 ptr 이 가리키고 있는 주소에서 4byte 크기만큼을 반환하게 되는 것입니다. *pf 도 마찬가지겠죠. pf 의 자료형은 struct flex 입니다. 그렇기에 pf 값이 count 주소 와 같더라도 *pf 는 그 시작 주소로부터 struct flex 크기만의 메모리를 더한 영역을 참조하게 됩니다. 즉 구조체 하나 전체 메모리인거죠.