원문 :
http://blog.yurihan.net/entry/stdstring-%EC%9D%98-formating
시발 낚였다.. gcc에서 완벽히 정상동작을 보장하지 않는다.
문제의 발단은 이거다.
내가 지금 윈도우에서 만든 변환 프로세스를 리눅스로 포팅중인데,
ATL 떡칠. CString의 향연/ 처음보는 CMapStringToString / CMapStringToOb 따위가 늘어져 있는데
파싱후에 CString::Format이 많아서 위의 링크에 쓴대로 정의하고
.Format( -> = format( 으로 치환해서 돌렸다.
처음에는 별문제가 없는데 컴파일해서 돌리다 보니 뻗는다.
문제를 한참 보아하니 format에서 256 에서 끊어버리고 뻗는다. 코드상으로는 시발 실패하면 버퍼를 두배로 늘리면서 계속 루프를 도는데..
그래서 length를 256을 65535 로 늘려봤다.
뻗는다. 시발.
아직 부족한가 싶어서 500000 정도로 10배 약간 안되게 늘렸다.
느리다.......심하게.........
그리고 뻗는다.........
조그맣게 테스트 후로그램을 짜서 테스트를 해 보았다... 실패했을때의 리턴값이.. -1이 아니다..
(구글링 해도 뾰족하게 안나오고 man 페이지를 봐도 다른거랑 묶여서 확실히 안나오더라. 그보다 술기운이라 눈에 안들어온다.)
가능한 사이즈의 length 를 밷고 죽더라. (실패든 성공이든 리턴값은 가능한 사이즈...)
그래서 코드 수정.
근데 args 에서 SIGSEGV 날리면서 뻗음....................
시발 어쩔?
원래 저녁때 오버플로만 확인하고 사이즈를 오십만으로 늘린 뒤에 돌렸는데 너무 느려서 퇴근뒤에 술한잔 하고 들어와서 확인했는데 뻗어있더라.
가뜩이나 술 마셔서 정신도 없는데.. 시발..
이후 테스트로 대략 한시간에 걸쳐 확인되고 테스트 한 결과이다.
length를 찍어봤는데 지금 돌리고 있는 루틴에서 35457983을 찍는다.
그러니 오십만으로 택도 없지.. 자그만치 삼천 오백 서삽 오만.. 50만 과 3천5백만.. ㅋ
대충 처리한 듯한 코드를 올려둔다. 참고들 하시라. (g++ 에서 돌렸다.)
stdargs는 알아서들 include 하시라.
int format_arg_list(std::string& out, int length, const char *fmt, va_list args)
{
if (!fmt) return -1;
int result = 0;
char *buffer = 0;
buffer = new char [length + 1];
memset(buffer, 0, length + 1);
result = vsnprintf(buffer, length, fmt, args);
out = buffer;
delete [] buffer;
return result;
}
std::string format(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
std::string s;
int length = 256;
int result = format_arg_list(s,length,fmt, args);
va_end(args);
if(result >= 256)
{
va_start(args, fmt);
format_arg_list(s,result+1,fmt, args);
va_end(args);
}
return s;
}
args 에서 뻗는건 그냥 va_start 한번 더 하는것으로 해결했고, 최초 length는 속도문제도 있고 하니 256으로 고정.
내가 지금 이 포스팅을 급하게 하는 이유는 내일이면 기억이 안날 듯 해서.
유리한
코드창고