Skip to content

45. 구조체와 메모리


1. 키워드

  • memcpy(Memory Copy)


2. 구조체와 메모리 활용하기

  • 구조체도 변수를 선언하거나 메모리를 할당하면 결국 메모리 공간을 차지하게 되므로 메모리 관련 함수도 사용할 수 있게 된다.
  • 이번에는 메모리 함수를 사용하여 구조체와 메모리에 값을 설정하는 방법과 구조체와 메모리의 내용을 복사하는 방법을 알아보자.


3. 구조체와 메모리를 간단하게 0으로 설정하기

  • 구조체의 멤버를 모두 0으로 만들려고 각 멤버에 접근하여 0을 저장하는 것은 꽤 번거로운 작업이다.


// 구조체 멤버에 일일이 접근하여 0을 저장
구조체변수.멤버1 = 0;
구조체변수.멤버2 = 0;
구조체변수.멤버3 = 0;
구조체변수.멤버4 = 0;


  • 구조체 변수를 선언할 때 {0,}처럼 {}를 사용하여 0으로 초기화할 수 있지만, 변수에만 사용할 수 있고 malloc 함수로 할당한 메모리에는 사용할 수 없다.


struct 구조체이름 변수이름 = {0,}; // 구조체 변수의 내용을 모두 0으로 초기화
                              // 단 malloc 함수로 할당한 메모리에는 사용할 수 없음


  • 일일이 멤버에 값을 설정하거나 {}를 사용하지 않고, 구조체 변수나 메모리의 내용을 한꺼번에 값을 설정하려면 memset 함수를 사용하면 된다.


memset(구조체포인터, 설정할값, sizeof(struct 구조체));
#include <stdio.h>
#include <string.h> // memset 함수가 선언된 헤더 파일

struct Point2D
{
    int x;
    int y;
};

int main()
{
    struct Point2D p1;

    memset(&p1, 0, sizeof(struct Point2D)); // p1을 구조체 크기만큼 0으로 설정

    printf("%d %d\n", p1.x, p1.y); // memset을 사용하여 0으로 설정했으므로 x, y 모두 0

    return 0;
}

// 0 0


  • memset 함수로 구조체 변수의 값을 설정할 때는 &p1과 같이 주소 연산자 &를 사용하여 변수의 메모리 주소를 구해서 넣어준다.
  • 그리고 설정할 값과 크기를 넣어준다.
  • 여기서는 구조체의 내용을 모두 0으로 설정했고, Point2D 구조체 크기만큼 값을 설정했다.


memset(&p1, 0, sizeof(struct Point2D)); // p1을 구조체 크기만큼 0으로 설정


  • printf 함수로 p1의 각 멤버를 출력해 보면 모두 0이 나온다.


001


  • 이번에는 malloc 함수로 할당한 동적 메모리에 값을 설정해 보자.


#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
#include <string.h> // memset 함수가 선언된 헤더 파일

struct Point2D
{
    int x;
    int y;
};

int main()
{
    struct Point2D *p1 = malloc(sizeof(struct Point2D)); // 구조체 크기만큼 메모리 할당

    memset(p1, 0, sizeof(struct Point2D)); // p1을 구조체 크기만큼 0으로 설정

    printf("%d %d\n", p1->x, p1->y); // memset을 사용하여 0으로 설정했으므로 x, y 모두 0

    free(p1); // 동적 메모리 해제

    return 0;
}

// 0 0


  • memset 함수로 메모리에 값을 설정할 때는 포인터를 그대로 넣어준다.
  • 왜냐하면 포인터 안에는 메모리 주소가 있으므로 &를 사용하지 않아도 된다.
  • 마찬가지로 설정할 값과 크기를 넣어준다.


memset(p1, 0, sizeof(struct Point2D)); // p1을 구조체 크기만큼 0으로 설정


  • 여기서도 printf 함수로 p1의 각 멤버를 출력해 보면 모두 0이 나온다.


002


  • 보통 memset 함수는 구조체나 메모리를 0으로 초기화할 때 사용하지만 각 상황에 따라서 0이 아닌 다른 값으로 초기화할 때도 사용할 수 있다.


4. 구조체와 메모리 복사하기

  • 매번 내용이 같은 구조체를 만들려면 상당히 번거롭다.
  • string.h 헤더 파일에 선언되어 있는 memcpy 함수를 사용하면 메모리의 내용을 다른 곳으로 복사할 수 있다.


memcpy(목적지포인터, 원본포인터, 크기);
목적지 포인터를 반환
#include <stdio.h>
#include <string.h> // memcpy 함수가 선언된 헤더 파일

struct Point2D
{
    int x;
    int y;
};

int main()
{
    struct Point2D p1;
    struct Point2D p2;

    p1.x = 10; // p1의 멤버에만 값 저장
    p1.y = 20; // p1의 멤버에만 값 저장

    memcpy(&p2, &p1, sizeof(struct Point2D)); // Point2D 구조체 크기만큼 p1의 내용을 p2로 복사

    printf("%d %d\n", p2.x, p2.y); // p1의 내용을 p2로 복사했으므로 10 20

    return 0;
}

// 10 20


  • 먼저 구조체 변수 p1, p2를 선언하고 p1의 멤버에만 값을 저장했다.
  • 그러므로 p2에는 저장된 값이 없다.


  • 이제 memcpy 함수를 사용하여 p1의 내용을 p2에 복사한다.
  • 여기서 &p1, &p2와 같이 구조체 변수 앞에 주소 연산자 &를 사용하여 변수의 메모리 주소를 구해서 넣어준다.
  • 마지막에는 복사할 크기를 넣어주는데 여기서는 구조체 크기를 구해서 넣어준다.


//      ↓ 목적지 포인터
memcpy(&p2, &p1, sizeof(struct Point2D)); // Point2D 구조체 크기만큼 p1의 내용을 p2로 복사
//           ↑ 원본 포인터


  • printf 함수로 p2의 각 멤버를 출력해 보면 p1의 멤버에 저장했던 10 20이 나온다.


003


  • 이번에는 malloc 함수로 할당한 동적 메모리끼리 복사하는 방법이다.


#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
#include <string.h> // memcpy 함수가 선언된 헤더 파일

struct Point2D
{
    int x;
    int y;
};

int main()
{
    struct Point2D *p1 = malloc(sizeof(struct Point2D));
    struct Point2D *p2 = malloc(sizeof(struct Point2D));

    p1->x = 10; // p1의 멤버에만 값 저장
    p1->y = 20; // p1의 멤버에만 값 저장

    memcpy(p2, p1, sizeof(struct Point2D)); // Point2D 구조체 크기만큼 p1의 내용을 p2로 복사

    printf("%d %d\n", p2->x, p2->y); // p1의 내용을 p2로 복사했으므로 10 20

    free(p1);
    free(p2);

    return 0;
}

// 10 20


  • 먼저 구조체 포인터 p1, p2를 선언하고 메모리를 할당한 뒤 p1의 멤버에만 값을 저장했다.
  • 그러므로 p2에는 저장된 값이 없다.


  • 이제 memcpy 함수를 사용하여 p1의 내용을 p2에 복사한다.
  • 여기서 p1p2는 메모리 주소를 담고 있는 포인터이므로 &를 사용하지 않고 그대로 넣어준다.


//     ↓ 목적지 포인터
memcpy(p2, p1, sizeof(struct Point2D)); // Point2D 구조체 크기만큼 p1의 내용을 p2로 복사
//         ↑ 원본 포인터


  • printf 함수로 p2의 각 멤버를 출력해 보면 p1의 멤버에 저장했던 10 20이 나온다.


004


  • 지금까지 구조체 변수에서 구조체 변수로, 동적 메모리에서 동적 메모리로 내용을 복사했지만 구조체 변수에서 동적 메모리로, 동적 메모리에서 구조체 변수로 내용을 복사할 수 있다.


struct Point2D p1;
struct Point2D *p2 = malloc(sizeof(struct Point2D));

memcpy(p2, &p1, sizeof(struct Point2D)); // 구조체 변수에서 동적 메모리로 복사
struct Point2D *p1 = malloc(sizeof(struct Point2D));
struct Point2D *p2;

memcpy(&p2, p1, sizeof(struct Point2D)); // 동적 메모리에서 구조체 변수로 복사

References