글 목록 보기

Lyn
조회 수 21666 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

속도가 아주 쬐~금 올라간 거 같긴 하네요.


역시 변경 이후는 PC를 쓸땐 상관 없는데 터미널 쓸때는 구석에 딱 맞춰서 마우스 이동하는게 쉽지 않기 때문이었습니다 =_=;

습관적으로 마우스 죽~ 끌면 터미널 창 밖으로 나가버리니...


이전시간은 OS 설치 30분, 데이터 백업 30분, 세팅맞추는데 15분 정도 해서 1시간 좀 넘게 걸렸네요. 데이터가 그리 많지 않다는 점이 컷지요.

?
  • profile
    Lyn 2013.09.28 22:07
    몇가지 테스트 해보니 생각보다 많이빠른데? ㅡ.ㅡ;;;

2013.09.27 20:20

VS2013 RC 설치해봄

Lyn
조회 수 13787 추천 수 0 댓글 0
Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

VS2013 RC를 설치 해 봤습니다.

왠지 설치 할 때 로그인을 하려면 하라는군요.


디바이스 간에 설정 같은거 연동해 준답니다... 여러군데 왔다갔다하면서 개발하는경우엔 편리하겠네요.


vs start.png


전 일단 연동하지 않았고 다음으로 진행 하니 옵션창이 뜹니다.
옵션이 좀 다양해졋네요.


start2.png


기념할만한 첫 실행 스샷입니다.
프로젝트 템플릿에 크게변화된건 없지만 왠지 파이썬과 타입스크립트가 기본으로 들어가 있습니다.

타입스크립트는 MS에서 만들었으니 그렇다 쳐도 파이썬은 좀 의외네요. 단 파이썬의 경우는 목록에는 있지만 툴이 기본설치되진 않아 따로 받아야 합니다.

proj.png

?

2013.09.23 07:50

현재 MSDN Download Page

Lyn
조회 수 19125 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

page.png


얼마전이랑 비교했을때 큰 변화는 없는데 Windows 8.1 Enterprise 가 올라왔네요.
그외엔 바뀐게 없어보입니다.

TAG •
?

Lyn
조회 수 21769 추천 수 0 댓글 0
Atachment
첨부 '5'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

이 코드는 Visual Studio 2012 Update3에서 테스트 되었습니다.


boost 1.46 부터 추가된 icl 컨테이너들은 범위를 가지는 데이터들을 넣을 수 있게 되어 있는 컨테이너다


이것들은 주로 일정 등의 데이터를 관리하기에 아주 좋게 되어 있고(boost 예제도 대부분 그런쪽입니다) 매우 확장성이 좋게 설계 되어 있어 다양한 용도로 활용 가능하지만 개인적으론 map의 기본형인 boost::icl::intervap_map<T1, T2> 의 형태가 매우 비상식적이라고 생각한다.


그래서 interval_map 을 원하는 형태로 만들어서 쓰고 싶었고 그 과정에서 알게된 것을 정리 해 본다.

내가 최종적으로 원하는 형태는 프로그램이 처음 시작할때 로딩되는 범위를 가지는 데이터를 관리 하고, 중복되는 경우가 있을경우 데이터 오류로 취급하여 예외를 발생 하는 형태입니다.


하나씩 알아보자면 interval_map 의 기본 개념은 기존의 std::map 과 같지만, 몇가지 추가적인 개념이 존재한다.

1. 구간.

구간이란 0~1, 2~3, 12:00~13:00 처럼 범위를 가지는 데이터. 수학시간에 배웠던것처럼 개구간, 폐구간, 반폐구간(좌/우) 가 존재합니다.
뭐 이건 문제될 것 없는 당연한 경우라고 보입니다.


2. Combine

입력한 구간이 서로 겹칠 경우 그 구간에 대해 Combine 동작을 시행합니다.
이것에 대해선 아래에서 마저 합니다.


3. 기본값

웃기게도 왠지 모르겠지만 (...) 기본값에 대한 처리를 변경할 수 있습니다.

여기에서 기본값이란 static T; 로 선언 했을때의 초기값입니다. int라면 0, float 라면 0.0f, std::string 이라면 길이0인 문자열인 식입니다.


1번 구간에 대해서는 별로 문제가 될 경우가 없을겁니다. 상식적으로 사용 할 수 있지요.
계속 울궈먹을 기본 코드 하나 넣겠습니다


#include <boost/icl/interval_map.hpp>
#include <string>
#include <utility>
#include <cstdio>

void wmain()
{
	using namespace std;
	using namespace boost;
	using namespace boost::icl;

	interval_map<int, wstring> ivm;

	ivm.add(make_pair(interval<int>::right_open(0, 2000), L"Right"));
	ivm.add(make_pair(interval<int>::left_open(2000, 3000), L"Left"));
	ivm.add(make_pair(interval<int>::closed(3000, 4000), L"closed"));
	ivm.add(make_pair(interval<int>::open(4000, 5000), L"Open"));

	auto it = ivm.find(1000);
	if(it != ivm.end())
	{
		wprintf(L"Find %s\n", it->second.c_str());
	}
	else
	{
		wprintf(L"Not Found");
	}
}


기본적인 사용 방법은 위와 같습니다. 구간을 지정해서 데이터를 넣고 find로 찾아오는형식으로 map과 완전히 동일합니다.

결과도 별다를게 없구요


1.png


위 코드를 자세히 보시면 3000 이라는 값은 left, closed 두개의 데이터가 겹치는 구간이라는 것을 알 수 있습니다.
이때 3000을 찾아서 출력해 보면 어떤 결과가 일어 나냐면....


2.png


이런 상황이 벌어집니다 (...) 
왜냐면 interval_map은 구간이 겹칠 경우 Combine 작업을 진행 하는데 이 단순히 interval_map<T1,T2> 로 선언한 Combine의  동작이 + 연산입니다.

즉 겹치는 구간의 데이터를 몽땅 더해서 출력해 버립니다. 숫자라면 값이 더해질것이고 문자열이라면 위처럼 문자열일 경우 두 문자열이 붙어서 나타납니다.

이 Combine 연산을 미리 몇가지 제공 하고 있는데, 이렇게 더한다던지, stl 컨테이너에 insert 를 한다던지 최대값/최소값으로 교체한던지 하는 기본적으로 많이 쓸만한 연산을 제공 하고 있습니다....만 내가 필요한 문제있을시 예외던지는 Combine은 제공 하지 않습니다.


두번째로 기본값 문제입니다. 위 코드를 수정해서 아래처럼 바꾼 후 실행해보겠습니다.


3.png



[0~2000) 구간에 빈 문자열을 넣었지만 찾을수 없다고 하고 있습니다.

왜냐면 그 Type의 기본값이 들어갈 경우 데이터를 넣지 않는것이 interval_map 기본형의 동작입니다


하지만 이 상황에서 내가 원한건 데이터 없음과, 빈 문자열을 데이터로 가지는것을 확실하게 구별 해야 하는겁니다.

값이 빈값인건 빈값이고,  없는건 없다고 할수 있어야되는 상황이더 많다고 생각되는데.... 왜 이런지는 모르겠습니다.


이 동작을 바꾸는 기능을 icl 은 제공 하고 있는데 두가지 옵션을 하나의 구조체로 만들어 총 4종류의 형태를 제공합니다.
partial_absorber, partial_enricher, total_absorber, total_enricher 의 4가지입니다.

여기서 뒤에 붙은 absorber, enricher 이 기본값을 어떻게 처리할지 결정합니다.
absorber는 날려버리고(초기형태) enricher 는 보존합니다. partial_enricher 로 바꾼 뒤 다시 한번 실행해 보겠습니다.


4.png


보다시피 찾아오는것에 성공하는 것을 볼 수 있습니다.

다음으로 앞에 붙은 partial, total 은.... 당췌 이게 어떻게 돌아가는지 모르겠습니다 =_=;;;;; 뭘로 하던 내가 원하는 동작에 지장이 없었기에 넘어갔습니다.
차후 추가적인 확인이 필요할듯 합니다. 아마 사용자 정의 type 에서만 영향을 미치는지도 모르겠습니다. 기본형은 이미 다 되어있고 ...


그리고 이제 combine 을 방지해야 하는데... combine functor 를 새로 만듬으로서 가능했습니다. 
겸사겸사 실수로 substract 를 호출하는것을 방지하기 위해 inverse functor 도 만들었습니다. 어차피 오류낼거니 궂이 따로 만들 필요는 없어서 그냥 같이 쓰도록 되었네요.


5.png


그 결과가 이 코드입니다. 중간에 less는 std::less 입니다. 비교 functor 가 템플릿에서 앞에 있는 바람에 저렇게 들어가버렷네요.

어쨋든 멋지게 assert 를 내 주네요. 원하는 동작이 만들어 졋습니다. 구간별 데이터를 안전하게 저장 할때 사용할수 있겠습니다.
궂이 사용 예를 추가해 보자면 ip 별 지역 정보를 넣어놓고 빠르게 검색할때 사용할 수 있겠네요.

TAG •
?

Lyn
조회 수 20223 추천 수 0 댓글 1
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

111111.png

SQL Server 2014를 제외한 거의 모든 제품이 정식 으로 등록되었네요.
개인적으론 Hyper-V + WIndows 2012R2에 큰 기대중입니다. VMWare 보며 부러워 했던 기능들이 많이 추가되었네요.

TAG •
?

Lyn
조회 수 25194 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

두번째 방법으로는 CRT의 예외 핸들러에서 UnhandledExceptionFilter로 데이터를 넘겨서 생성하는 방법인데요...
이는 안정적이고 정석적이지만 치명적인 단점으로 CRT에서 던지는 예외가 하나가 아니라는겁니다... 


어쨋든 코드를 보면


#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>

using namespace std;

#pragma comment(lib, "dbghelp.lib")

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
	MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
	std::wstring DumpFileName = L"dmpfile.dmp";

	MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
	MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
	MinidumpExceptionInformation.ClientPointers = FALSE;

	if (DumpFileName.empty() == true)
	{
		::TerminateProcess(::GetCurrentProcess(), 0);
	}

	HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		nullptr,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, nullptr);

	MiniDumpWriteDump(GetCurrentProcess(),
		GetCurrentProcessId(),
		hDumpFile,
		MiniDumpNormal,
		&MinidumpExceptionInformation,
		nullptr,
		nullptr);

	::TerminateProcess(::GetCurrentProcess(), 0);

	return 0;
}
void InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
	EXCEPTION_POINTERS ExceptionPointer;
	EXCEPTION_RECORD ExceptionRecord;
	_CONTEXT ContextRecord;

	ZeroMemory(&ContextRecord, sizeof(ContextRecord));
	RtlCaptureContext(&ContextRecord);

	ZeroMemory(&ExceptionRecord, sizeof(EXCEPTION_RECORD));
	ExceptionRecord.ExceptionCode = STATUS_INVALID_CRUNTIME_PARAMETER;	
	ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Eip;
		
	ExceptionPointer.ExceptionRecord = &ExceptionRecord;
	ExceptionPointer.ContextRecord = &ContextRecord;

	TopLvFilter(&ExceptionPointer);
}
void main()
{
	SetUnhandledExceptionFilter(TopLvFilter);
	_set_invalid_parameter_handler(InvalidParameterHandler);
	atoi(nullptr);	 
}



구조는 간단합니다. RtlCaptureContext 를 이용해서 현재 쓰래드의 Context를 캡쳐 해 오고, 익셉션 코드와 현재 코드가 실행중인 위치를 넘겨 주면 되는데요..
x86 시스템에서 현재 실행중인 위치는 Eip 레지스터에 있기 때문에 캡쳐해온 Context에서 Eip를 
ExceptionAddress로 넘겨 주면 됩니다.


이 방식은 안정적이고 백신이 오진을 할 가능성도 없고 Windows 8 에서도 아무 문제 없이 작동 하지만 ... 위에서 말한것처럼 예외가 이거 하나가 아니라는게 문제가 됩니다.
예를들어 메모리 할당 예외는 _set_invalid_parameter_handler 로 처리 할 수 없습니다. 하지만 어차피 몇개 안되기도 하고 (...) 그냥 몇개 더 만들어주면 될 문제지요.


정말 골때려 지는건 3rd party 에서 SetUnhandledExceptionFilter 를 호출해서 자기껄로 만들어버리는 라이브러리가 있다는겁니다 =_=; 적은 내안에만 있는게 아닌거죠...그래서 첫번째 방법과 두번째 방법을 모두 적용해 두는게 좋다고 생각 합니다


TAG •
?

Lyn
조회 수 32502 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

사후 디버깅을 위해 가장 많이 쓰이는 방법중 하나가 메모리 덤프를 남기는 방법입니다.

보통 아래와 같은 형태로 구현 하게 되는데요. 과연 이 프로그램은 덤프가 남을까요?


#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>


using namespace std;

#pragma comment(lib, "dbghelp.lib")

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
	MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
	std::wstring DumpFileName = L"dmpfile.dmp";

	MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
	MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
	MinidumpExceptionInformation.ClientPointers = FALSE;

	if (DumpFileName.empty() == true)
	{
		::TerminateProcess(::GetCurrentProcess(), 0);
	}

	HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
		GENERIC_WRITE,
		FILE_SHARE_WRITE,
		nullptr,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, nullptr);

	MiniDumpWriteDump(GetCurrentProcess(),
		GetCurrentProcessId(),
		hDumpFile,
		MiniDumpNormal,
		&MinidumpExceptionInformation,
		nullptr,
		nullptr);

	::TerminateProcess(::GetCurrentProcess(), 0);

	return 0;
}

void main()
{
	SetUnhandledExceptionFilter(TopLvFilter);	
	atoi(nullptr);
}


네. 결론부터 말하자면 위 코드에서는 덤프가 남지 않습니다.
왜냐면 CRT 에서 에러가 발생하면 UnhandledExceptionFilter 를 CRT가 자신의 예외 핸들러로 다시 세팅 하기 때문입니다.

그러나 우리가 바라는건 별로 친절하지도 않은 (...) CRT의 에러메세지가 아니라 메모리 덤프지요.

우리가 원하는대로 덤프를 남기는 방법은 여러 가지가 있지만 그 중 한가지로 해결 해 보겠습니다.

이번에 사용 할 방법은 코드를 패치해서 CRT가 감히 내가 만든 예외처리기를 바꾸지 못하도록 (...) 하는 방법입니다



#include <Windows.h>
#include <DbgHelp.h>
#include <cstdio>
#include <string>

using namespace std;

#pragma comment(lib, "dbghelp.lib")

BYTE HotPatchingBackup[5];

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI NullSetUnhandledExceptionFilter(
  _In_  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
)
{
    return nullptr;
}

void InstallAPIHook_SetUnhandledExceptionFilter()
{
    BYTE *pSetUnhandledExceptionFilter;

    DWORD ProtectOption = 0;
    DWORD Temp = 0;

    pSetUnhandledExceptionFilter = (BYTE*)&SetUnhandledExceptionFilter;

	HANDLE hSelfProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE, ::GetCurrentProcessId());
	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, PAGE_EXECUTE_WRITECOPY, &ProtectOption);     	

    memcpy(HotPatchingBackup, pSetUnhandledExceptionFilter, 5);

    *pSetUnhandledExceptionFilter = 0xE9;
	pSetUnhandledExceptionFilter++;
    *((DWORD *)(pSetUnhandledExceptionFilter)) = ((DWORD)NullSetUnhandledExceptionFilter) - ((DWORD)pSetUnhandledExceptionFilter + 4);	
	pSetUnhandledExceptionFilter--;

	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, ProtectOption, &Temp);

	CloseHandle(hSelfProcess);
}

void UnInstallAPIHook_SetUnhandledExceptionFilter()
{
    BYTE *pSetUnhandledExceptionFilter;

    DWORD ProtectOption;
    DWORD Temp;

    pSetUnhandledExceptionFilter = (BYTE*)&SetUnhandledExceptionFilter;
	
	HANDLE hSelfProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE , FALSE, ::GetCurrentProcessId());
	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, PAGE_EXECUTE_READWRITE, &ProtectOption);    

    memcpy(pSetUnhandledExceptionFilter, HotPatchingBackup, 5);

	VirtualProtectEx(hSelfProcess, (void *)pSetUnhandledExceptionFilter, 5, ProtectOption, &Temp);     

	CloseHandle(hSelfProcess);
}

LONG __stdcall TopLvFilter(PEXCEPTION_POINTERS pExceptionPointer)
{
    MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInformation;
    std::wstring DumpFileName = L"dmpfile.dmp";

    MinidumpExceptionInformation.ThreadId = ::GetCurrentThreadId();
    MinidumpExceptionInformation.ExceptionPointers = pExceptionPointer;
    MinidumpExceptionInformation.ClientPointers = FALSE;

    if (DumpFileName.empty() == true)
    {
        ::TerminateProcess(::GetCurrentProcess(), 0);
    }

    HANDLE hDumpFile = ::CreateFile(DumpFileName.c_str(),
        GENERIC_WRITE,
        FILE_SHARE_WRITE,
        nullptr,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, nullptr);

    MiniDumpWriteDump(GetCurrentProcess(),
        GetCurrentProcessId(),
        hDumpFile,
        MiniDumpNormal,
        &MinidumpExceptionInformation,
        nullptr,
        nullptr);

    ::TerminateProcess(::GetCurrentProcess(), 0);

    return 0;
}

void main()
{
    SetUnhandledExceptionFilter(TopLvFilter);
    InstallAPIHook_SetUnhandledExceptionFilter();
    atoi(nullptr);
    UnInstallAPIHook_SetUnhandledExceptionFilter();
}


API 훅을 해서 필터를 바꾸려 하면 아무 일도 하지 않는 NullSetUnhandledExceptionFilter 이 호출되도록 하여 막는 방법입니다...
멋있어 보이기는 하지만 이 코드는 64bit/32bit 를 따로 만들어야 하고, 심지어 윈도우 8 에서는 이 코드가 정상적으로 동작 하지 않습니다 (....) 아마도 강화된 보안때문에 그런게 아닌가 싶은데...

어쨋든 윈도우7 까지는 정상적으로 덤프가 남습니다.


그럼 이런 편법 말고 좀 정석적인 방법이 필요한데... 그건 다음글로...

TAG •
?

Lyn
조회 수 22981 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
http://www.microsoft.com/ko-KR/download/details.aspx?id=38188
 

사실 온라인 다운로드 버전 받을 때 스크롤 쭉 내려서 읽어 보면 나와 있는데 ...
온라인 업데이트 프로그램을 받은 후 VS2012.2.exe /layout 처럼 /layout 옵션을 주어 시작하면 설치하지 않고 다운로드만 받습니다.

다운로드 후 인터넷이 안되는 PC로 복사해 가서 설치 하면 됩니다.
용량이 한 2G쯤 되니 시간은 좀 걸립니다(본격 원본보다 더 큰 패치)

?
  • ?
    아리수 2013.04.15 05:21
    VS2012 설치 하면서 미리 업데이트를 받아 두려고 했더니 설치 중이라는 메시지와 함께 실행이 되지 않더군요...꼼꼼하더군요..ㅋㅋ..
    작업하시는데 참고하세요...^^

Lyn
조회 수 34009 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

역시 이번에도 아무도 관심가져주지 않는 (...) 불쌍한 주제를 하나 가지고 나와봤습니다


C++의 표준 라이브러리인 stl 의 특징이라고 하면 반복자(iterator)의 존재하고 할 수 있는데요...

이 반복자들은 여러가지 종류가 있습니다. 

정방향 or 역방향, 임의접근 or 순차접근, 상수 or 비상수 등 여러가지 조합의 반복자를 생성 할 수 있는데요 ...


이중 방향은 애초에 별도의 함수로 제공되고 (begin vs rbegin), 임의접근이냐 순차접근이냐는 컨테이너의 특성에 달린 문제었습니다.
그러나 상수 반복자(const_iterator)는 별도의 함수가 제공되지 않았는데요, C++특성상 비상수 -> 상수 의 변환은 자유롭기 때문입니다.

그래서 비상수 반복자를 리턴하는 begin 을 호출 후 상수반복자 type 의 변수에 대입하여 사용하는 식으로 구현 되었었지요.



하지만 C++11에선 상수반복자를 리턴하는 cbegin 이 추가되었습니다.
왜냐구요? auto 키워드의 존재 때문입니다. 

사용해보신 분은 아시겠지만 auto 는 한번 써보고 나면 없으면 stl 쓰기 싫어질 정도로 반복자와 함께 사용할때 아주 편한 기능인데, auto는 인터프리팅 언어들처럼 동적타입 변수가 아니라 우변의 type을 유추해서 컴파일타임에 type이 정해지기 때문에 begin 으로 리턴받은 반복자는 반드시 비상수 반복자가 됩니다.


그렇기에 C++11에서는 auto와 함께 사용할 수 있는 상수 반복자를 리턴하는 별도의 함수가 추가되었습니다. 애초에 상수반복자를 리턴하기 때문에 auto로 선언해도 좀 더 안전한 코드를 짤 수 있게 됩니다.


TAG •
?

Lyn
조회 수 27213 추천 수 0 댓글 3
Atachment
첨부 '8'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++11 표준이 완성 되면서 상당히 많은 기능이 표준 라이브러리에 추가 되었습니다.

이들중 상당수는 완전히 새로운 클래스로 제공되는 것이 많지만 기존 기능을 보안하는 식으로 추가된것도 많습니다.

그중 가장 많이 쓰인다고 볼 수 있는 string 관련으로도 여러가지가 추가 되었습니다.


아래 코드는 최신의 Visual Studio 2012 에서 작성되었습니다.


첫번째로 Native언어 답게 메모리를 직접 관리 할 수 있는 함수가 추가 되었습니다.


1.png


원래 대부분의 stl 객체가 그렇든 한번 할당 한 메모리는 데이터 사이즈가 줄어든다 해도 줄이지 않았습니다.
하지만 C++11에서는 shrink_to_fit 매소드를 제공하여 메모리를 줄일 수 있도록 하고 있습니다.



2.png


그 다음으론 front, back, pop_back 함수의 추가입니다.
이름답게 front, back 은 각각 첫글자, 마지막 글자를 리턴하며 pop_back은 맨뒤에서 한글자를 잘라냅니다.



사실 이 다음부터가 가장 쓸만한 부분입니다.
C++의 string 은 숫자 관련 함수를 제공하지 않아 C의 atoi, itoa 처럼 배열을 기반으로 하는 함수를 사용하거나 stringstream 을 사용하여 문자열을 조립하는 과정을 필요로 하였습니다. C++11에서는 그것과 관련된 함수를 추가 하였습니다.


3.png


가장 기본적인 활용법입니다 stoi 함수는 문자열을 숫자로 변환합니다. type 에 따라 stoi, stol, stoll, stoul, stoull, stof, stod, stold로 바꿔쓸 수 있습니다.
각각 int, long, long long, unsigned long, unsigned long long, float, double, long double 로 변환하는 함수입니다.


4.png

뒤에 변환할 수 없는 문자열이 있을경우, 변환 가능한 부분 까지만 변환 후 몇글자가 변환되었는지 얻어올 수 있습니다.


5.png

진법 변환도 가능합니다.
16진수 100은 256으로 8진수 100은 64로 정상적으로 변환 되었습니다.

16진수 8진수만이 아니라 7진수 9진수 등 중간단계에 있는 진법으로도 정상적으로 변환이 가능합니다.


6.png


문자열을 언제나 숫자로 바꿀 수 있는것은 아니기 때문에 2 종류의 예외를 던질 가능성이 있습니다.
각각 숫자로 변환 불가능한 문자열과 너무 길어서 숫자의 범위를 넘어서는 문자열을 변환 시도 할 경우의 예외입니다.


7.png

기본적으로 0x를 앞에 붙일경우 0만 인식하여 0으로 변환 되지만 16진법으로 변화할 경우에 한정해서 0x를 인식하여 정상적인 문자열로 판단합니다.
8진법 변환의 경우 앞의 0 한자리만 인식하여 0으로 변환된것을 볼 수 있습니다.



지금까진 문자열을 숫자로 변환 하였지만 반대의 기능도 있습니다.


8.png


반대의 기능으로 to_string 함수를 제공합니다.
모든 정수/실수 타입에 대해 오버로딩 되어 있기때문에 단순히 호출만 하면 됩니다.


단 실수의 경우 무조건 소수점 7번째 자리에서 반올림하여 6자리로 표기하게 되어 있습니다.
자리수 조절이 필요 할 경우 format 기능이 있는 boost:format, stringstream, sprintf 등의 기존 함수를 사용하여야 합니다

?
  • ?
    노땅개발자 2012.09.24 16:45
    정리 참 잘해주셨네요.
    제 블로그에 출처 명시하고 퍼갑니다. ^^
  • ?
    최고의프로그래머 2012.09.25 17:05
    좋은 글 감사합니다. 출처명시하에 스크랩합니다
  • ?
    노력왕 2013.09.16 19:51
    와우 좋은 정보 입니다.
    제 블로그에도 퍼갈게요 좋은 하루 되세요 ^^

Board Pagination Prev 1 ... 3 4 5 6 7 8 9 10 11 12 13 Next
/ 13