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포인터는 사다리 그림 다 그려가면서 익혀보시길...
포인터와 배열의 차이점과 유사점을 익히시고, 타고급언어에서 보기 힘든 포인터의 매력에 흠뻑 빠지실거에요!
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
90742 [질문] 삼국지 관련 질문입니다. 형주가 원래 땅도 크고 사람도 많은 주였나요? [8] sand4533 16/09/29 4533
90740 [질문] 인터넷이 너무 느린데 이런 경우에는 어떻게 하는게 좋을까요? (데탑+usb 무선랜카드) [2] 도시의미학1928 16/09/29 1928
90739 [질문] 김영란법에 저촉될까요? [5] 해먹이필요해3011 16/09/29 3011
90738 [질문] [LOL] 룰루 서폿 아이템 질문입니다. [9] 베이비블루2754 16/09/29 2754
90737 [질문] 신축 아파트 분양시 은행 중도금 대출 부적격 세대의 계약금은 어떻게 되는지요? [2] Red Key4740 16/09/29 4740
90736 [질문] 스프링 DI 와 AOP 개념이 잘 이해가 안됩니다. [6] 트루키5043 16/09/29 5043
90735 [질문] 30대 중반 얼굴에 자꾸 털이 늘어 납니다. [3] 크리스티아누2904 16/09/29 2904
90734 [질문] 여수로 당일치기 여행을 갈 예정입니다. [10] 쉬군2706 16/09/29 2706
90733 [질문] 스마트폰 구매 문의 ace_creat1685 16/09/29 1685
90732 [질문] 운동부족의 마른 사람은 어떻게 해야 할까요? [4] 유라2569 16/09/29 2569
90731 [질문] XX 안경처럼 보이나요? [13] CLAMP 가능빈가3012 16/09/29 3012
90730 [질문] 공유기 와이파이 2.4ghz, 5ghz 둘 다 켜놓으시나요 하나만 켜놓으시나요? [3] Love Fool5860 16/09/29 5860
90729 [질문] 음주운전하는 심리는 뭔가요? [40] 어느새주말4193 16/09/29 4193
90728 [질문] 자동차 허브 베어링 질문입니다. [2] Helloween2377 16/09/29 2377
90727 [질문] 원룸.대형TV.중소기업제품.PC연결도? 추천 부탁드립니다 몽유도원3499 16/09/29 3499
90726 [질문] [하스스톤] 부활사제 잘잡는덱좀 부탁드립니다. [7] 선동가4451 16/09/29 4451
90725 [질문] [하스스톤] 폰스폰 음악멈춤 현상 [2] 모노크롬2847 16/09/29 2847
90724 [질문] 다큐멘터리에서 알려주는 정보는 얼마나 신뢰성 있나요? [5] im98n2851 16/09/29 2851
90723 [질문] 이런 회사가 있다면, 몇일 일하시겠다고 하시겠나요? [53] 마르키아르4877 16/09/29 4877
90722 [질문] DJI 공홈에서 산 물건이 트래킹이 안됩니다... 50b2055 16/09/29 2055
90721 [질문] 주차되어있는 차를 긁었는데 비용 관련 질문드립니다! [15] 삭제됨6463 16/09/29 6463
90720 [질문] 운동열심히 하는 사람입장에선 고지방 저탄수가 조금 이해가안됩니다 [11] Ciara.3967 16/09/29 3967
90719 [질문] Shawn Mendes - Mercy 같은 노래 없을까요? 산악왕트래킹1858 16/09/29 1858
목록 이전 다음
댓글

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