전에 이 문제로 한참을 삽질한 적이 있었는데요. 생각나서 작성해봅니다.
가끔 STL에 Array를 저장하고 싶을 때가 있습니다. 예를 들면 Mac주소(6바이트짜리 Byte Array)라던지, MD5 해쉬값(16바이트짜리 Byte Array) 아니면 굳이 String을 char array 형태로 다루고 싶다거나...
다음과 같이 하면 될 것 같은데 막상 해보면 안됩니다.
위의 소스코드를 빌드하면 다음과 같은 오류가 발생합니다.
좀 잘 맞춰주면 빌드가 될것 같은데 아무리 맞춰봐도 안됩니다. ㅎㅎ
결론부터 얘기하자면 이겁니다.
우리가 데이터를 STL 자료구종 저장할 때... 데이터의 "주소"를 넘기는게 아니고 그냥 데이터를 Call by Reference로 바로 넘깁니다. 그러면 데이터가 STL 내부에서 할당된 메모리에 "복사"된 후, 사본이 STL에 저장됩니다. 따라서 우리가 넘긴 데이터의 메모리를 delete하더라도 STL 안에 저장된 데이터는 문제가 없습니다. (복사본이니까)
또한, 이 메모리는 STL에서 delete되거나 STL 자료구조 자체가 파괴될 때 저절로 delete됩니다. 따라서 우리는 STL을 쓸때 메모리 핸들링에 대한 걱정을 하지 않아도 됩니다. STL의 가장 편리한 점 중 하나죠. ^^
그런데 건네진 데이터가 Array인 경우에는... Array를 STL 데이터구조에 "삽입"하다가 문제가 생깁니다.
Array Size만큼의 메모리를 Allocate한 다음, 넘겨받은 Array를 복사하기 위해 "대입"연산을 수행하는데.. 대입연산자가 정의되어 있지 않으니까 문제가 생기는 거죠. 그런데 이게 에러메시지만 보고는 짐작하기가 쉽지 않습니다.
이런 경우에 생각해볼 수 있는 가장 쉬운 해결책은 데이터를 BYTE Array로 쓰지 말고 헥사값 스트링으로 풀어서 쓰는 것입니다. 예를 들어 위의 벡터를 vector<string> 과 같이 정의한 다음 Mac주소를 "002481B155A6"과 같은 string으로 저장하는 거죠.
만약 반드시 Array 형태로 저장해야 한다면 다음과 같이 하는 방법이 있습니다.
C++에서 구조체/클래스를 선언하면 내부적으로 "디폴트 복사생성자"가 정의되어 대입연산이 가능해집니다.
뭐 약간 꼼수같은 느낌이 없진 않지만... 되긴 합니다. ^____^
가끔 STL에 Array를 저장하고 싶을 때가 있습니다. 예를 들면 Mac주소(6바이트짜리 Byte Array)라던지, MD5 해쉬값(16바이트짜리 Byte Array) 아니면 굳이 String을 char array 형태로 다루고 싶다거나...
다음과 같이 하면 될 것 같은데 막상 해보면 안됩니다.
위의 소스코드를 빌드하면 다음과 같은 오류가 발생합니다.
1>------ Build started: Project: StlTest, Configuration: Debug Win32 ------
1>Compiling...
1>StlTest.cpp
1>c:\program files\microsoft visual studio 8\vc\include\vector(1125) : error C2440: 'initializing' : cannot convert from 'const BYTE [6]' to 'unsigned char [6]'
1> There is no context in which this conversion is possible
... 중간 생략 ...
1>StlTest - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
1>Compiling...
1>StlTest.cpp
1>c:\program files\microsoft visual studio 8\vc\include\vector(1125) : error C2440: 'initializing' : cannot convert from 'const BYTE [6]' to 'unsigned char [6]'
1> There is no context in which this conversion is possible
... 중간 생략 ...
1>StlTest - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
좀 잘 맞춰주면 빌드가 될것 같은데 아무리 맞춰봐도 안됩니다. ㅎㅎ
결론부터 얘기하자면 이겁니다.
Array는 "대입연산자"와 "복사생성자"가 정의되지 않았기 때문에 STL의 인자가 될 수 없다.
우리가 데이터를 STL 자료구종 저장할 때... 데이터의 "주소"를 넘기는게 아니고 그냥 데이터를 Call by Reference로 바로 넘깁니다. 그러면 데이터가 STL 내부에서 할당된 메모리에 "복사"된 후, 사본이 STL에 저장됩니다. 따라서 우리가 넘긴 데이터의 메모리를 delete하더라도 STL 안에 저장된 데이터는 문제가 없습니다. (복사본이니까)
또한, 이 메모리는 STL에서 delete되거나 STL 자료구조 자체가 파괴될 때 저절로 delete됩니다. 따라서 우리는 STL을 쓸때 메모리 핸들링에 대한 걱정을 하지 않아도 됩니다. STL의 가장 편리한 점 중 하나죠. ^^
그런데 건네진 데이터가 Array인 경우에는... Array를 STL 데이터구조에 "삽입"하다가 문제가 생깁니다.
Array Size만큼의 메모리를 Allocate한 다음, 넘겨받은 Array를 복사하기 위해 "대입"연산을 수행하는데.. 대입연산자가 정의되어 있지 않으니까 문제가 생기는 거죠. 그런데 이게 에러메시지만 보고는 짐작하기가 쉽지 않습니다.
이런 경우에 생각해볼 수 있는 가장 쉬운 해결책은 데이터를 BYTE Array로 쓰지 말고 헥사값 스트링으로 풀어서 쓰는 것입니다. 예를 들어 위의 벡터를 vector<string> 과 같이 정의한 다음 Mac주소를 "002481B155A6"과 같은 string으로 저장하는 거죠.
만약 반드시 Array 형태로 저장해야 한다면 다음과 같이 하는 방법이 있습니다.
C++에서 구조체/클래스를 선언하면 내부적으로 "디폴트 복사생성자"가 정의되어 대입연산이 가능해집니다.
뭐 약간 꼼수같은 느낌이 없진 않지만... 되긴 합니다. ^____^
'C++' 카테고리의 다른 글
DllMain에서 하면 안되는 12가지 작업들 (0) | 2009.11.06 |
---|---|
갖가지 라이센스에 대한 명쾌한 정리!! (0) | 2009.10.26 |
delete와 delete[]를 구분해서 사용해야 하는 이유 (0) | 2009.07.30 |
new 연산자를 사용한 동적 메모리 할당 실패시 예외 처리 (8) | 2009.05.17 |
TIME_WAIT를 남기지 않는 세션종료 (Graceful Shutdown) (13) | 2009.04.19 |