리뷰
https://www.acmicpc.net/problem/3217
이 문제 덕분에 malloc의 작동 방식에 대해 더욱 깊게 알게 되었다.
전역 변수
- M : 메모리 최대값의 크기를 정의할 상수 변수
- n : 명령의 개수를 저장할 변수
- Node : 연결 리스트의 노드를 정의할 구조체
- dic : 각 변수가 할당된 노드 포인터를 저장할 해시맵
함수
없음
문제풀이
- n값을 입력 받고, 임의의 root노드를 한개 생성해 준다.
- n번의 while루프를 수행하고, 변수 q에 각 명령에 해당하는 문자열을 입력 받아준다.
- 모든 명령엔 괄호안에 인자가 주어지므로 변수 inner에 인자를 문자열로 저장해 준다.
- malloc명령이 주어질 경우 변수 var에 변수명을 문자열로 입력 받아주고, 변수 size에 inner를 정수로 바꿔 저장한다.
- Node포인터 변수 cur에 root를 저장하고, 무한 루프를 수행해 준다.
- cur이 마지막 노드 이면서 할당 후 메모리의 끝이 M보다 작을경우 노드를 맨끝에 삽입해 준다.
- 만약 노드를 할당할 수 없는 경우 dic[var]을 nullptr로 저장해 준다.
- cur이 중간 노드지만 동적 할당해 줄 공간이 있을 경우 노드를 삽입해 준다.
- 위 두 케이스에 맞는 삽입 위치가 나올 때 까지 연결리스트를 순회해 준다.
- print명령이 주어질 경우 dic에 inner가 없거나 값이 nullptr일 경우 0을, 아니라면 노드의 st값을 출력한다.
- free명령이 주어질 경우 dic에 inner가 없거나 값이 nullptr일 경우 continue를, 아니라면 현재 노드를 삭제한다.
트러블 슈팅
- 해시맵의 키를 변수명, 값을 vector<Node*>로 구현하여 중복 free호출 시 순차적으로 지워주는 로직을 작성하였다.
- 동일한 변수에 malloc명령이 추가로 인입된 경우 해당 값으로 덮어써주어 AC를 받았다.
참고 사항
- malloc은 연속된 메모리 구조를 가질 필요 없이 할당할 수 있는 메모리 공간만 있으면 할당할 수 있다.
- 동일한 변수에 malloc을 추가로 진행할 경우 이전에 동적할당한 메모리를 해제할 수 없어 누수가 발생한다.
정답 코드
#include<iostream>
#include<unordered_map>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int M = 1e5;
int n;
struct Node {
string var;
int st, ed;
Node* prev;
Node* next;
Node(string VAR, int ST, int ED) : var(VAR), st(ST), ed(ED), prev(nullptr), next(nullptr) {}
};
unordered_map<string, Node*> dic;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
Node* root = new Node("root", 0, 0);
while (n--) {
string q; cin >> q;
auto it1 = find(q.begin(), q.end(), '(');
auto it2 = find(q.begin(), q.end(), ')');
string inner = string(it1 + 1, it2);
if (q.find("malloc") != string::npos) {
string var = string(q.begin(), q.begin() + 4);
int size = stoi(inner);
Node* cur = root;
while (1) {
if (cur->next == nullptr) {
//cout << cur->var << " " << cur->st << " " << cur->ed << "\n";
int st = cur->ed + 1;
int ed = cur->ed + size;
if (ed <= M) {
Node* node = new Node(var, st, ed);
node->prev = cur;
cur->next = node;
dic[var] = node;
}
else dic[var] = nullptr;
break;
}
int st = cur->ed + 1;
int ed = cur->ed + size;
//cout << cur->var << " " << cur->st << " " << cur->ed << " " << cur->next->var << " " << cur->next->st << " " << cur->next->ed << "\n";
if (ed < cur->next->st) {
Node* node = new Node(var, st, ed);
node->next = cur->next;
node->next->prev = node;
node->prev = cur;
cur->next = node;
dic[var] = node;
break;
}
cur = cur->next;
}
}
else if (q.find("print") != string::npos) {
auto it = dic.find(inner);
if (it == dic.end() || !it->second) cout << 0 << "\n";
else cout << it->second->st << "\n";
}
else {
auto it = dic.find(inner);
if (it == dic.end() || !it->second) continue;
else {
Node* node = it->second;
if (node->next != nullptr) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
else node->prev->next = nullptr;
it->second = nullptr;
delete node;
}
}
}
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[G5] 백준 18112번 이진수 게임 C++ 너비 우선 탐색, 비트마스킹 (1) | 2025.07.11 |
---|---|
[L2] 프로그래머스 n^2 배열 자르기 C++ 구현 (2) | 2025.07.11 |
[G3] 백준 9997번 폰트 C++ 백트래킹, 비트마스킹 (1) | 2025.07.10 |
[G3] 백준 2830번 행성 X3 C++ 비트마스킹, 수학 (3) | 2025.07.09 |
[G5] 백준 21775번 가희와 자원 놀이 C++ 구현, 시뮬레이션, 트리셋 (0) | 2025.07.08 |