2016-11-29 7 views
0

힙에서 std :: unordered_map을 선언하고 일부 연산을 수행 한 다음 해제하는 구문은 무엇입니까? 내가하고 있어요 :std :: unordered_map <int32_t, int32_t> 힙에 선언 됨

std::unordered_map<int32_t, int32_t> *map_temp_last_close = new std::unordered_map<int32_t, int32_t>; 
*(map_temp_last_close[val]) = *(int32_t*)(read_buffer + 30); //this happens multiple times in a loop 
int32_t some_val = val * (*(map_temp_last_close[val])) 
map_temp_last_close->clear(); 
delete(map_temp_last_close); 

편집 : 이유는 힙에 그것을 가지고해야합니까? 나는 끊임없이 네트워크로부터 데이터를 수신하는 함수를 항상 가지고 있으며, 어떤 경우에는이를 처리하기 위해 맵에 데이터를 저장한다. 지도 사용이 끝나면 다시 프로토콜에서 메시지를받지 못하므로지도가 필요 없지만 함수가 무한 루프에 있으므로지도가 범위를 벗어나지 않습니다. 네트워크에서 읽기). 그래서 free 또는 delete 또는 뭔가를 호출하여 메모리를 확보하고 싶습니다.

+3

왜 힙에서이 작업을 수행해야합니까? 왜 스택에 없습니까? –

+0

@SergeRoussak 편집을 참조하십시오. – user2635088

+2

@ user2635088 : 로컬 스택 변수 (공식적으로 자동 저장 기간을 가진 지역 변수)는 둘러싸는 범위 끝에서 삭제됩니다. 범위는 함수보다 작을 수 있습니다. '{}'를 사용하여 함수 내에서 스코프를 생성하십시오. 또는 이미 수행중인 것처럼'map() '을'clear()'라고 부르면 문제가되는 자원을 복구 할 수 있습니다 ('sizeof (unordered_map)')는 무시할 수 있습니다. 관심을 가져야하고, 'clear()'가 그것을 처리해야한다). –

답변

2

오류는 중괄호의 위치 지정입니다. 먼저 의 참조 해제 후 데이터 구조에 색인을 생성해야합니다.

std::unordered_map은 이미 힙에 데이터를 저장하고 있기 때문에 처음에는 힙에 넣지 않았지만 실제로 필요한 경우 가장 간단한 방법은 다음과 같습니다.

auto map_temp_last_close = std::make_unique<std::unordered_map<int32_t, int32_t>>() 
(*map_temp_last_close)[val] = *(int32_t*)(read_buffer + 30); 
int32_t some_val = val * (*map_temp_last_close)[val]; 

//map object will get destroyed automatically when map_temp_last_close goes out of scope, but if you want to delete it earlier, you can use: 
map_temp_last_close.reset(); 

이 힙에 std::unordered_map하고 관리하는 지역 unique_ptr 변수를 생성합니다 map_temp_last_close이 범위를 벗어나 때마다,이 가 자동으로 삭제됩니다 (귀국일 예외 또는 현재 범위가 종료해서 통해 일을) 지도. 또한지도가 자동으로 수행되므로 파괴하기 전에 clear에 전화 할 이유가 없습니다.

참고 :
이 식 (read_buffer의 종류에 따라) 가장 가능성 : *(int32_t*)(read_buffer + 30)이 정의되지 않은 동작입니다.

+0

감사합니다. 그래서'read_buffer'는'recv'를 호출 할 때 네트워크로부터 바이트를 받으면 채워진 char 배열입니다. 네트워크 프로토콜이 해당 위치에 int32_t가있을 것을 지시하면 여전히 정의되지 않은 동작입니까? 내가 알고있는'int32_t' 값이 특정 범위를 벗어났다면 프로토콜에 오류가 있으며 이에 따라 해당 동작을 처리 할 수 ​​있다는 것을 알고 있습니다. – user2635088

+0

@ user2635088 : 예, 두 가지 방법으로 정의되지 않은 동작입니다. 먼저 위반 사항입니다. 두 번째는 정렬 위반입니다 ('30'은 sizeof (int32_t)의 배수가 아닙니다). 값을 얻기 위해서는'memcpy (& some_val, read_buffer + 30, 4)'를 사용하십시오. 정렬 오류를 허용하는 플랫폼을 사용하는 경우 컴파일러는 모든 비트를 원래대로 효율적으로 32 비트 이동을 생성하지만 형식적으로 잘 정의됩니다. 그리고 정렬이 중요한 플랫폼에서는 작업 코드를 얻습니다. –

+0

@BenVoigt는 (* map_temp_last_close) [val]에 복사하기 위해'memcpy'를 사용할 수 있습니까? 그것은'memcpy (& ((* map_temp_last_close) [val]), read_buffer + 30, 4)이 될까요? – user2635088