Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어 구조체 포인터의 동적 메모리 할당 완벽 가이드

C 언어에서 구조체 포인터(pointer to structure)는 구조체 전체의 시작 주소를 저장하는 포인터입니다. 이를 활용하면 연결 리스트(linked list), 트리(tree), 그래프(graph)처럼 복잡한 자료구조를 효율적으로 구현할 수 있습니다.

특히 구조체 포인터로 멤버에 접근할 때는 일반적인 점(.) 연산자 대신 화살표 연산자(->)라는 특수 연산자를 사용한다는 점이 핵심입니다.

구조체 포인터 선언

구조체 포인터는 다음 형식으로 선언합니다.

struct tagname *ptr;

예를 들어 학생(student) 구조체에 대한 포인터는 아래와 같이 선언할 수 있습니다.

struct student *s;

구조체 멤버 접근하기

포인터가 가리키는 구조체의 멤버에 접근하려면 화살표 연산자(->)를 사용합니다.

ptr->membername;

예를 들어 s->sno, s->sname, s->marks처럼 작성하면 각각 학번, 이름, 점수 멤버에 바로 접근할 수 있습니다.

예제 1: malloc을 활용한 동적 메모리 할당

다음 프로그램은 사용자로부터 인원 수를 입력받아, 그 크기만큼 구조체 메모리를 malloc()으로 동적 할당한 뒤 이름과 나이를 저장하고 출력합니다. 포인터 연산(ptr+i)을 통해 각 구조체 요소에 순차적으로 접근하는 방식을 확인할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>
struct person {
    int age;
    float weight;
    char name[30];
};
int main(){
    struct person *ptr;
    int i, n;
    printf("Enter the number of persons: ");
    scanf("%d", &n);
    // n명의 struct person을 위한 메모리 동적 할당
    ptr = (struct person*) malloc(n * sizeof(struct person));
    for(i = 0; i < n; ++i){
        printf("Enter name and age respectively: ");
        // 첫 번째 구조체 멤버 접근: ptr->name, ptr->age
        // 두 번째 구조체 멤버 접근: (ptr+1)->name, (ptr+1)->age
        scanf("%s %d", (ptr+i)->name, &(ptr+i)->age);
    }
    printf("Displaying Information:\n");
    for(i = 0; i < n; ++i)
        printf("Name: %s\tAge: %d\n", (ptr+i)->name, (ptr+i)->age);
    return 0;
}

실행 결과

위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.

Enter the number of persons: 1
Enter name and age respectively: bhanu 24
Displaying Information:
Name: bhanu Age: 24

예제 2: 구조체 배열과 포인터 함께 사용하기

이번에는 구조체 배열과 포인터를 조합하여 여러 명의 관리자(Manager) 정보를 입력받고 출력하는 예제입니다. 포인터를 증가시키는(p++) 방식으로 다음 구조체 요소로 이동하며, 문자 입력 시 발생하는 버퍼 문제를 임시 변수(temp)로 처리하는 팁도 담겨 있습니다.

#include<stdio.h>
// 외부 구조체 선언 //
struct Manager{
    char Name[15];
    int Age;
    char Gender;
    float Level;
    char Role[50];
    char temp;
}m[20];
void main(){
    // 반복문 변수 및 포인터 변수 선언 //
    int i;
    struct Manager *p;
    // 포인터 정의 //
    p=&m;
    // 사용자 입력 받기 //
    for (i=1;i<3;i++){// 2명의 관리자 데이터 입력 //
        printf("Enter the Name of manager %d : ",i);
        gets(p->Name);
        printf("Enter the Age of manager %d : ",i);
        scanf("%d",&p->Age);
        scanf("%c",&p->temp);// 버퍼 비우기 //
        printf("Enter the Gender of manager %d : ",i);
        scanf("%c",&p->Gender);
        printf("Enter the level of manager %d : ",i);
        scanf("%f",&p->Level);
        scanf("%c",&p->temp);// 버퍼 비우기 //
        printf("Enter the role of manager %d : ",i);
        gets(p->Role);
        p++;
    }
    // 출력을 위해 포인터를 다시 초기화 //
    p=&m;
    // 결과 출력 //
    for (i=1;i<3;i++){
        printf("The Name of Manager %d is : %s\n",i,p->Name);
        printf("The Age of Manager %d is : %d\n",i,p->Age);
        printf("The Gender of Manager %d is : %c\n",i,p->Gender);
        printf("The Level of Manager %d is : %f\n",i,p->Level);
        printf("The Role of Manager %d is : %s\n",i,p->Role);
        p++;
    }
}

실행 결과

위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.

Enter the Name of manager 1 : Hari
Enter the Age of manager 1 : 55
Enter the Gender of manager 1 : M
Enter the level of manager 1 : 2
Enter the role of manager 1 : Senior
Enter the Name of manager 2 : Bob
Enter the Age of manager 2 : 60
Enter the Gender of manager 2 : M
Enter the level of manager 2 : 1
Enter the role of manager 2 : CEO
The Name of Manager 1 is : Hari
The Age of Manager 1 is : 55
The Gender of Manager 1 is : M
The Level of Manager 1 is : 2.000000
The Role of Manager 1 is : Senior
The Name of Manager 2 is : Bob
The Age of Manager 2 is : 60
The Gender of Manager 2 is : M
The Level of Manager 2 is : 1.000000
The Role of Manager 2 is : CEO

핵심 정리

  • 구조체 포인터는 구조체 전체의 시작 주소를 저장합니다.
  • 멤버 접근 시 화살표 연산자(->)를 사용합니다.
  • malloc() 함수를 사용하면 실행 중에 필요한 만큼 구조체 메모리를 동적으로 할당할 수 있어, 유연한 자료구조 구현이 가능합니다.
  • (ptr+i) 또는 ptr++ 같은 포인터 연산을 활용하면 구조체 배열처럼 여러 요소를 순회할 수 있습니다.