-
C++ fill_n vs memset, 무슨 차이가 있을까쾌락없는 책임 (공부)/C++ 짜잘이 2022. 2. 28. 23:06반응형
서론
알고리즘 문제 풀이를 하다 보면 배열이나 vector 등을 초기화해야 하는 일이 많습니다. 첫 생성시 0으로 초기화 된다는 사실이 있지만 이것도 환경따라 다를 수 있고 또는 0이 아닌 다른 값으로 초기화해야 하는 일이 있습니다.
그럴때 for문을 사용하기 싫어서 fill_n, memset 등의 함수를 사용해서 값을 세팅하게 됩니다. 그런데 언제 한번 2차원 배열 등을 사용할 때 초기화가 제대로 되지 않는 경우가 있었습니다. 그래서 오늘 두 함수에 대한 차이점을 알아보기 위해서 글로 정리하게 되었습니다.
두 함수의 차이
일단 헤더부터 차이가 있습니다. fill 관련 함수들은 <algorithm> 헤더에 있으며 memset는 <cstring>에 있습니다. 그리고 memset의 경우 c 에서 파생된 함수로 fill_n 보다 조금 더 빠르다는 이야기가 있지만 실제로 체감할 정도는 아니며 gcc6.2 에서는 둘다 같은 코드를 만들어 낸다는 이야기도 있습니다.
#include <iostream> #include <algorithm> #include <cstring> #include <limits> using namespace std; int long long arr[5]; void printArr(){ for(int i = 0; i < 5; i++){ cout << arr[i] << " "; } cout << '\n'; } int main(){ arr[1] = __LONG_LONG_MAX__; printArr(); // 0 9223372036854775807 0 0 0 memset(arr, 1, sizeof(arr)); printArr(); // 72340172838076673 72340172838076673 72340172838076673 72340172838076673 72340172838076673 fill_n(arr, sizeof(arr), 1); printArr(); // 1 1 1 1 1 }
제일 큰 차이는 위 코드에서 보이게 됩니다. memset으로 long long 배열을 1로 초기화 하려고 했는데 이상한 값이 나오게 됩니다.
cout << bitset<16>(arr[1]) << '\n'; // 0000000100000001
이걸 16진수로 출력을 해보면 00000001 이 반복되는 모습을 볼 수 있습니다. 아마도 8바이트 단위로 초기화를 해주는것 같아서 이런 문제가 발생한 것 같습니다. 그래서 0, -1을 제외한 경우 memset을 사용할 때 데이터 타입의 길이에 따라서 원하는 값이 나오지 않을 수 있습니다!
결론
결론을 내자면 데이터타입에 따라, 초기화 하는 값이 0, -1이 아니라면 fill_n 사용을 고려하자!
참고 사이트
- 속도와 관련한 이야기
- memset이 넘기는 단위와 관련한 이야기
반응형'쾌락없는 책임 (공부) > C++ 짜잘이' 카테고리의 다른 글
[C++] C++ 의 '1LL'은 무슨 뜻일까? (0) 2022.06.16 C++ make_pair vs {} (0) 2022.03.06 C++ pimpl과 관련한 이야기들 (0) 2022.02.16 C++ 구조체, 클래스 패딩 (0) 2022.01.24 C++ 에서 증감 연산자 오버로딩, 전위, 후위 연산자를 구별하는 방법 (0) 2022.01.11