구조체를 동적할당하여 값을 직접접근하여 넣고 출력하기
#include <iostream>
#include <malloc.h>
#include <cstring>
using namespace std;
typedef struct studentTag {
char name[10]; //char 1바이트 * 10 = 10바이트
int age; //4바이트
double gpa; //8바이트
} student;
int main()
{
student* s;
s = (student*)malloc(sizeof(student)); //student 구조체속 속성들의 크기합만큼 동적할당(10+4+8)=22바이트 할당
/*24로 나오는 이유는 메모리의 정렬위함.
*
* 구조체 속 name이 10바이트, age가4바이트, gpa가 8바이트인데
* 정렬이라함은
* 가장 큰 단위씩 맞추기 위해 name에 2바이트를 추가하여 12, 4, 8로 정렬시킴.
*/
cout << "학생구조체의 크기: " << sizeof(student) << " bytes" << endl;
if (s == NULL) {
cout << "메모리가 부족합니다.";
return 1;
}
strcpy_s(s->name, "Park"); //문자열 student구조체 s의 name에 직접접근하여 Park을 복사해서 넣는다
s->age = 20; // == (*).age = 20 과 동일함
cout << "이름: " << s->name << " / 나이: " << s->age;
free(s); //메모리해제
}
Malloc이란?
C와 C++에서 동적 메모리 할당때에 사용하는 함수
반환타입이 (void*)를 반환하기에 할당시킬 포인터 변수와 동일한 자료형을 캐스팅 해야합니다.
해제시에는 free()함수로 메모리를 해제 해야합니다.
구조체에 접근할 때에는 .보다는 ->로 하는 것이 직접적으로 접근하기 때문에 보기에도 좋습니다.
이번 내용에서 가장 유익했던 점
구조체를 malloc으로 메모리를 동적 할당하게되면 정렬을 위해 가장 큰 자료크기 단위로 할당하게 됩니다.
Student 구조체에
Char형 배열 10칸 = 1바이트*10 = 10바이트
int형 변수 하나 = 4바이트
double형 변수 하나 = 8바이트
= 총 22바이트
가 할당 될 줄 알았더니 24바이트가 할당되었습니다.
이유는
구조체의 Char형이 10바이트로 가장 큰 단위인 double의 8바이트 단위로 끊기지 않기때문에 2바이트를 추가하여 12바이트를 맞춘것입니다.
CPU가 데이터를 효율적으로 처리 하도록 메모리의 경계를 맞추기위해 추가시킨 것이라고 합니다.
이해가 제대로 안되던게 구조체 순서가 char name[10], int age, double gpa 면 가장 큰 단위인 double에 맞춰서
10(name) + (패딩:6) + 4(age) + (패딩:4) + 8(gpa) = 32가 나와야 한다 생각했는데,
구글링과 gpt로 알아보니 컴파일러가 메모리 정렬을 알아서 필요한 메모리만 할당해주기 위해 최적화시켜주어서
10(name) + (패딩:2) + 4(age)까지 16으로 맞춰지니 뒤에 8(gpa)만 추가하여 24로 할당된 것 이였습니다.
최적화가 안되었다면 32가 할당되는 것이였습니다.
다른 예시로 같은 코드지만 gpa와 age의 순서를 바꾼것입니다.
typedef struct studentTag {
char name[10]; //char 1바이트 * 10 = 10바이트
double gpa; //8바이트
int age; //4바이트
} student;
객체지향도 순차적으로 읽기때문에 name다음 double을 읽습니다. 이때 8단위를 맞추기위해 name에 10바이트에 패딩은 2가 아니라 6을 추가시켜주어야합니다. 그래야 다음 gpa의 메모리 배치를 맞출 수 있기 때문입니다.
gpa 이후는 age도 8단위에 맞춰야하므로, name(10) + (6패딩) + gpa(8) + age(4) + (4패딩) = 32바이트 할당이 됩니다.
선언 순서에 따라서도 메모리 크기가 달라지기 때문에 크기가 작은 것 부터 선언하는것이 최적이라 볼 수 있겠습니다.
'C++' 카테고리의 다른 글
[백준] C++ 2164번 - 카드2 (0) | 2024.11.09 |
---|---|
C언어로 쉽게 풀어쓴 자료구조 1장 연습문제 풀기 (1) | 2024.11.09 |
[C++] 동적 배열 스택(Stack) 구조 구현 (4) | 2024.11.05 |
[C++] 구조체로 표현한 희소행렬과 두 행렬의 덧셈과 전치 (3) | 2024.11.02 |
[C++] 구조체와 포인터 전달로 다항식 덧셈 알고리즘 (0) | 2024.10.31 |