본문 바로가기
알고리즘

[C++] resize vs assign vs memset vs fill

by persi0815 2024. 7. 3.

요약

1. resize는 크기 조절에 중점을 두고,

2. assign은 초기화 및 대체,

3. memset은 바이트 단위 초기화,

4. fill은 범위 내 값 설정

 

구체적 설명

resize

벡터의 크기를 지정된 크기로 변경한다. 만약 크기를 늘리면 새 요소들은 기본값으로 초기화된다. 크기를 줄이면 초과된 요소들이 제거된다.
- 특징: 크기를 변경하면서 새 요소들을 기본값으로 채우거나, 기존 요소를 유지하는 것이다.
- 주로 사용되는 상황: 벡터의 크기를 동적으로 조정해야 할 때 사용된다.

#include<vector>
vector<int> vec; 

vec.resize(10);
#include<vector>
vector<vector<int>> vec; 

vec.resize(10, vector<int>(10));

 

assign

벡터의 "크기를 지정된 값"으로 설정하고 모든 요소를 지정된 값으로 초기화한다.
- 특징: 기존 요소를 모두 제거하고 새 값을 할당하여 벡터를 초기화하는 것이다.
- 주로 사용되는 상황: 벡터의 모든 요소를 특정 값으로 한 번에 초기화하거나, 다른 컨테이너의 요소들로 대체할 때 사용된다.

#include<vector>
vector<int> vec; 

vec.assign(10, 5); 벡터를 크기 10으로 초기화하고, 모든 요소를 5로 설정
#include<vector>
vector<vector<int>> vec;

vec.assign(10, vector<int>(10, 5)); // 행 크기, 열 크기, 초기화 값

 

memset -> 속도는 빠르지만, 초기화할 수 있는 형태에 제한이 있음

배열이나 메모리의 특정 블록을 원하는 값(주로 0)으로 설정한다.

주의할 점은 바이트 단위로 값을 설정하므로 0과 -1 이외의 값으로 초기화할 때는 문제가 발생할 수 있다. 

 

- 특징: "바이트 단위"로 메모리를 설정하는 것이다. 일반적으로 배열을 초기화할 때 사용된다.

   -> vector<int> v를 초기화할때 사용하면, 벡터 내부의 포인터나 메타데이터가 손상될 수 있다.
- 주로 사용되는 상황: C 스타일 배열이나 원시 메모리 블록을 초기화할 때 사용된다. (1차원 배열)

#include<cstring>
int arr[10]; // 원시 메모리 블록

memset(arr, 0, sizeof(arr));
#include<cstring>
#include<vector>
vector<int> v[MAX];

for (int j = 1; j <= V; j++) {
    v[j].clear(); // 이게 정석
    memset(&v[j], 0, sizeof(v[j])); // 이처럼 첫 주소가 들어가면 가능은 한데, 데이터 손상될 수 있음
}


fill -> 속도는 느리지만, 보다 다양한 형태로 초기화할 수 있다. = 안전함

지정된 범위의 모든 요소를 특정 값으로 설정한다. 범위 기반 알고리즘으로, 벡터, 배열 등 모든 반복 가능한 컨테이너에 사용할 수 있다.
- 특징: 특정 범위 내의 모든 요소를 같은 값으로 설정하는 것이다. 범위 기반 알고리즘으로 다양한 컨테이너에 적용할 수 있다.
- 주로 사용되는 상황: 이미 할당된 컨테이너의 모든 요소를 특정 값으로 채울 때 사용된다.

#include <algorithm>
#include <vector>
vector<int> vec(10); 

fill(vec.begin(), vec.end(), 5);
#include <algorithm>
#include <vector>
vector<int> v[MAX];

for (int j = 1; j <= V; j++) {

    //fill(&v[j], v + V + 1, 0); // 컴파일 에러 
    
    for (auto& row : v) { // 시간복잡도가 크다
        fill(row.begin(), row.end(), 0);
    }
}