알고리즘 공부/C++
[G1] 백준 3217번 malloc C++ 구현, 연결 리스트, 해시맵, 문자열
마달랭
2025. 7. 10. 21:33
리뷰
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