PGR21.com
- PGR21 관련된 질문 및 건의는 [건의 게시판]을 이용바랍니다.
- (2013년 3월 이전) 오래된 질문글은 [이전 질문 게시판]에 있습니다.
통합 규정을 준수해 주십시오. (2015.12.25.)
Date 2016/09/19 00:15:57
Name 호시조라 린
Subject [질문] C언어 구조체 포인터 질문좀 드리겠습니다..
안녕하세요

C언어 자기참조 구조체에 대해서 공부하고있는데 한가지 의문이 들어서 질문드립니다.

typedef struct lists
{
    char *name;
    int grade;

    struct lists *next;
} list;

list *student;

student = (list *)malloc(sizeof(list));


여기서 어떻게 해서 student에 lists 구조체가 메모리 할당되어, 그걸 가리키는 포인터값이 들어가는지 헷갈립니다..

말이 애매해서 더 자세하게 적어보자면..


1.  list *student; 를 해서 lists구조체만 가리킬수 있는 구조체포인터 student를 선언하고
2. student = (list *)malloc(sizeof(list)); 으로 메모리 어딘가에 lists 구조체 크기만큼의 메모리를 동적할당해서 반환되는 void포인터를 (list )로 캐스팅해서 student에 넣습니다.

여기서 궁금한게 단지 메모리를 할당해서 반환되는 포인터를 넣었을 뿐인데 그게 구조체가 생성되는걸로 볼수 있는건가요? (list *)로 캐스팅하고 student로 넣는 것만으로도 어떻게 구조체가 생성되는지 이해가 되지 않습니다..

malloc으로 메모리 할당받고 그걸 가리키는 포인터를 특정 형으로 캐스팅하면 , 특정 형을 정의 한 것이랑 같게 되는건가요..?

통합규정 1.3 이용안내 인용

"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
16/09/19 00:50
수정 아이콘
malloc(sizeof(list))
이 명령이 list의 크기만큼 메모리를 할당하라는 얘기라
특정 형을 정의한것과 같다고 볼 수 있겠죠

malloc의 return이 void형 포인터라 student에 넣기 위해
student의 자료형인 list * (list형 포인터) 로 만들어줘야 한다고 알고 있습니다.
호시조라 린
16/09/19 17:58
수정 아이콘
정의가 곧 메모리 할당이군요
16/09/19 01:15
수정 아이콘
어차피 메모리에는 바이트, 비트 단위로 여러 값이 나열되어 있을 뿐이니까요. 구조체나 변수 같은 개념은 프로그래밍 중인 프로그래머와 컴파일러가 고려하는거고, 실제 프로그램이 동작하면서는 별로 상관이 없습니다.
구조체 크기 만큼의 빈 공간이 있고, 그 공간을 구조체 처럼 사용하는거죠.
호시조라 린
16/09/19 17:59
수정 아이콘
할당한 메모리를 구별하는게 헷갈리네요..
16/09/19 01:37
수정 아이콘
포인터는 본체를 가르치는 키입니다

malloc은 구조체에 필요한만큼 공간을 할당한다는 의미입니다.

말록으로 할당한 공간과 그것을 가리키는 키를 생성했으니까 말씀하신기 맞습니다
호시조라 린
16/09/19 18:00
수정 아이콘
할당후 포인터 캐스팅하면 정의인 것이군요
..
16/09/19 03:40
수정 아이콘
C 언어를 배울 때 장벽인 개념이 포인터지요.
예전에 학생들을 가르칠 땐 이렇게 가르치곤 했습니다.

내가 집을 구매한다고 할 때 포인터와 포인터 캐스팅의 본체인 malloc 은 다음과 같은 역할을 합니다.

1. 포인터 = 구매할 집의 행정지 주소
2. malloc 를 통한 메모리 공간 확보 = 실제 거주하는 집 건물

포인터를 이해하는 가장 간단한 방법은, 메모리라는 하드웨어의 구조를 이해하는 것으로부터 시작합니다.
- 메모리는 엄청나게 거대한 저장공간의 block 으로 이뤄져 있다고 연상합니다.
- 그리고 c 언어에서 포인터는 각 block 의 [위치] 를 이야기 합니다.
- 포인터는 메모리의 해당 위치에 무엇이 있는가를 알 수 없습니다. 그저 무조건 [메모리의 특정 block] 만을 가르킵니다.
- 그리고 포인터 주소를 캐스팅하여 그 공간에 위치하는 것이 [무엇인가] 를 컴파일러에게 알려줍니다.
- 하지만 포인터에게 가르킨 주소에 그 [무엇인가] 가 존재하지 않고 다른 녀석이 있다면 프로그램은 오류를 뿜습니다.
- 그래서 포인터에게 주소를 가르키기전에, 그 [무엇] 을 malloc 를 통해 할당하고, 거기엔 [무엇] 이 있을 것임을 미리 결정해둡니다.
- 마지막으로 malloc 으로 만들어둔 [무엇] 의 주소를 포인터에게 가르켜주며 [무엇] 이 해당 block 에 있음을 캐스팅으로 전달합니다.
이 과정만 그냥 떠올려두시면 쉽습니다.
1차원 포인터를 이해하시고 나면, 2,3차원 포인터도 큰 문제 없이 넘어가실 수 있습니다 ^^
호시조라 린
16/09/19 18:07
수정 아이콘
구조체는 일반적인 정의든, 포인터변수에 메모리 할당후 캐스팅해서 시작주소를 기록하든 '무엇'에 접근하는 방법이 다를 뿐인건가요?
자유의영혼
16/09/19 05:06
수정 아이콘
사실 별로 좋은 방식은 아니지요.
구조체가 메모리상에서 관리되는 방식에 따라 달라질 수 있는데, C에서는 메모리상에 순차적으로 위치하는 저장공간이라고 가정하고 있는 것이지요.
C++에서는 student = new list; 와 같이 좀더 나은 방식이 사용됩니다.
호시조라 린
16/09/19 18:01
수정 아이콘
c만의 메모리 시스템인가요..
16/09/19 05:16
수정 아이콘
네 맞습니다. int a;로 선언한 것도 사실 같은 일을 합니다. 그게 정적이냐 동적이냐 하는 차이만 있습니다.
호시조라 린
16/09/19 18:08
수정 아이콘
같은 것이군요..
바나클대장
16/09/19 10:52
수정 아이콘
여기서 궁금한게 단지 메모리를 할당해서 반환되는 포인터를 넣었을 뿐인데 그게 구조체가 생성되는걸로 볼수 있는건가요? (list *)로 캐스팅하고 student로 넣는 것만으로도 어떻게 구조체가 생성되는지 이해가 되지 않습니다..

=> 구조체가 생성된다기 보다는 구조체의 크기만큼 할당한 메모리를 프로그래머 맘대로 쓰겠다 입니다.
할당해서 반환되는 메모리 영역을 프로그래머가 list 로 생각하고 쓰는것입니다.
구조체의 크기만 동일하면 다른 포인터로
변환해서 쓸 수 있습니다. c언어는 실제 할당한 메모리 영역에 프로그래머가 변환해서 쓰려고 하는 구조체가 실제로 들어있는지 전혀 상관하지 않습니다.
다만 캐스트하는 포인터의 사이즈를 계산해서 그 만큼만 프로그래머가 write 할 수 있도록 해 줍니다.
그래서 잘못될 여지가 많습니다. 메모리 사이즈만 같은 아이로 바꿔서 이것저것 해봐도 실제로 write가 일어나기 전까지는 합당한 문장이니까요.

c++나 java는 실제 메모리 영역에 할당된 오브젝트가 프로그래머가 캐스트 하려는 오브젝트와 같은지 체크합니다.
예를 들어 list 포인터는 실제 list object 가 있거나 list object의 자식들만 point 할 수 있습니다.
호시조라 린
16/09/19 18:10
수정 아이콘
구조체라는걸 특별히 만들다기보단 메모리를 그조체같이 쓴단 것인가요..
바나클대장
16/09/20 00:09
수정 아이콘
그렇습니다.
1. malloc(sizeof(list)) 이 문장이 실행되면 list 구조체의 크기만큼의 공간이 메모리 어딘가에 할당됩니다. 이 공간은 예약되어 있고 사이즈는
char 1 바이트 , int 4 바이트, 포인터 8 바이트 ( 64비트 ) 합해서 13바이트가 할당되어야 합니다. (사실은 4바이트 단위로 할당하므로 3바이트를 패딩하여 16바이트가 할당됩니다.)
이 할당된 공간은 꼭 list 구조체만 쓸수 있는것이 아닙니다. 예를 들어 4바이트 int 네 개가 들어있는 integer array 도 사이즈가 같으므로 충분히 쓸 수 있습니다.
int* pIntArray = (int *)malloc(sizeof(list)); 이렇게 해도 아무 문제 없다는 이야기입니다. 다만 실제 16바이트가 할당되었으므로 5번째 integer를 읽고 쓴다던가 하면 내가 할당한 곳이 아니므로 ( 다른 사람이 사용하고 있는 공간일 수 있습니다) 프로그램이 어떻게 행동할지 아무도 모릅니다. segmentation fault 가 날 수 도 있고 undefined behavior 가 일어날 수 있습니다.

2. student = (list *)malloc(sizeof(list));
이 문장이 실행되면 메모리에 할당한 16바이트에 list 구조체의 한 인스턴스가 들어 있다고 말해주는 것입니다.
그래서 student->name 이라고 하면 컴파일러가 어디서 얼만큼 읽어와야 하는지 알 수 있습니다.
student->grade 는 할당된 메모리에서 4바이트 더 지나서 읽어야 한다는 것을 구조체를 보고 컴파일러가 알 수 있습니다.
16/09/19 14:01
수정 아이콘
사실 구조체만큼의 메모리 그것이 구조체란 인스턴스의 실체입니다. 즉 그만큼 크기의 메모리를 잡아서 구조체타입으로 캐스팅해서 쓰는게 정상적인 오퍼레이션이 되는 것이죠. 다만 차이가 있다면 구조체를 지역변수, 전역 변수로 할당하는 것과 메모리 영역만 다른 것이죠.
malloc은 힙영역에 생성되는 것이고 지역변수로 선언했다면 지역변수의 스택 영역, 전역 변수라면 코드메모리 영역에 생성되는 것이 차이입니다.
사실 포인터의 타입이란게 거창한 것이 아닙니다. 포인터는 주소값이라 플랫폼에 따라 32비트 64비트인 값을 가지고 있을 뿐입니다. 그것에 어떤 타입의 포인터든 그 사실은 변하지 않습니다. 구조체의 포인터든 배열의 포인터든 보이드포인터든 그냥 숫자값이 들어있는 것이죠. 그런데 그냥 그렇게 쓰면 사람들이 햇갈리니까 그 주소의 실제로 무엇이 있냐를 타입으로 나타내는 것입니다. 저 주소에는 4층짜리빌라(int)가 있어 15층짜리 배열이 있어 이렇게요.
그래야 그 포인터의 있는 무언가를 사용하고자할때 혼동이 없으니까요. 실제로 4층짜리 빌라밖에 없는데 5층에 접근한다던가 이러면 문제가 생기니까 int라는 것을 가리키는 포인터다 int* 라고 선언을 하는 것이에요. 사실 C++, 자바에서 등장하는 객체를 이용한 상속같은 것도 실제로 동작은 포인터로 동작 하는 것이에요.
호시조라 린
16/09/19 18:37
수정 아이콘
그렇군요.. 답변 감사합니다
3막1장
16/09/19 20:07
수정 아이콘
선언과 할당의 차이를 이해하셔야 될 것 같네요.
선언만 해서는 이용할 수 없어요.
할당을 하셔야 합니다.
C에서는 malloc C++에서는 new 로...
열혈강의 C포인터랑 C++ 추천 드립니다.
특히 C포인터는 사다리 그림 다 그려가면서 익혀보시길...
포인터와 배열의 차이점과 유사점을 익히시고, 타고급언어에서 보기 힘든 포인터의 매력에 흠뻑 빠지실거에요!
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
90171 [질문] Pgr 개인화 설정 관련 질문 [2] Alcohol bear2042 16/09/19 2042
90170 [질문] [LOL] 코코선수 사건 관련 질문입니다 [2] 불통왕3133 16/09/19 3133
90169 [질문] 고혈압 관련 질문드립니다.. [8] 상남자2585 16/09/19 2585
90168 [질문] [WOW] 직업추천 부탁드립니다. [28] Secundo7354 16/09/19 7354
90167 [질문] 헤어진 후 시간이 지나고 다시 만나보신분 계신가요? [23] 삭제됨24293 16/09/19 24293
90166 [질문] 오스만투르크에 관한 책 추천 부탁드려요 [2] 현실적인2509 16/09/19 2509
90165 [질문] C언어 구조체 포인터 질문좀 드리겠습니다.. [18] 호시조라 린4309 16/09/19 4309
90164 [질문] WoW를 위한 컴퓨터 업그레이드 문의드립니다. [6] 맛있는사이다2258 16/09/18 2258
90162 [질문] 컴알못이 여쭤봅니다.블루스크린 증상과 PC새구입에 관하여. [2] 꼬비2366 16/09/18 2366
90161 [질문] e스포츠의 규모와 열정을 보여주는 [12] codin3117 16/09/18 3117
90160 [질문] [하스스톤] 친선전 퀘스트 하실분~^^ [3] 피즈2589 16/09/18 2589
90159 [질문] 맥주만으로 취하는게 가능하겠죠? [27] Rebirth14584 16/09/18 14584
90158 [질문] 이정도 상태면 장애가 심각한건가요?? 아니면 그렇게 심각한게 아닌가요?? [8] 잘가라장동건3610 16/09/18 3610
90157 [질문] 코수술후 코가 휘었는데요. 병원 책임이 없는걸까요 [2] 삭제됨2289 16/09/18 2289
90156 [질문] 배틀넷 앱 베타 되시는분 있으신가요? bellhorn2153 16/09/18 2153
90155 [질문] 오리진 결제 질문 드립니다 Love.of.Tears.2421 16/09/18 2421
90154 [질문] Aseprite 사용법에 대해서 질문! 물리쟁이3100 16/09/18 3100
90153 [질문] [LOL] 원딜로 포블 먹은 후 행동 지침은 뭔가요? [17] 빠니쏭4039 16/09/18 4039
90152 [질문] 어르신에게 부분유료화를 설명하다가 [14] codin3558 16/09/18 3558
90151 [질문] 섬유유연제 같은 향 나는 향수 추천 부탁드립니다. [14] 티티5812 16/09/18 5812
90150 [질문] 레몬쥬스를 만드려는데 단 맛 첨가 관련해서 궁금한게 있습니다. [3] 인간사료1776 16/09/18 1776
90149 [질문] 오프라인에서 커피크림 판매하는 곳을 찾고 있습니다. [4] 황승언2413 16/09/18 2413
90148 [질문] 주택청약저축은 이동이 불가능한가요? [1] 김소현10944 16/09/18 10944
목록 이전 다음
댓글

+ : 최근 1시간내에 달린 댓글
+ : 최근 2시간내에 달린 댓글
맨 위로