2009-07-20 5 views
-1

문자열이 있는데 그 문자열에 대한 참조를지도에 넣고 싶습니다.지도에 저장된 할당 중 문자열 메모리 관리

string m_tmp; 
map<pair<string, string>, string&> m; 
m[pair<string, string>("Foo","Bar")]= m_tmp; 

then, I change the m_tmp; 
m_tmp="DFDFD"; 

맵은 모든 플랫폼에서 여전히 새로운 값으로 m_tmp을 참조합니까?

아래의 더미 프로그램에 따르면 s의 주소는 변경되지 않습니다 (Linux AS4, gcc 3.4). 이와 관련하여 메모리 관리가 플랫폼간에 동일합니까? S의 주소 (변수가 C++로 그렇게 할 수 없습니다), 문자열의 내용이 변경 될 수 변경되지 않지만 연주 할 때

#include<string> 
#include<iostream> 

using namespace std; 

int main() 
{ 

    string s="Sasha"; 
    cout<<&s<<endl; 
    s="Bar"; 
    cout<<&s<<endl; 
    s="Foo"; 
    cout<<&s<<endl; 
} 

답변

2

왜이 대신 해달라고 :

map<pair<string, string>, shared_ptr<string> > m; 

나에게 안전 같은데.

+0

이 이미 –

+0

으로 변경되었습니다.이 작업은 btw가됩니다. map , string> m; [쌍 ("Foo", "Bar") "문자열"]; ?? 방금 ​​알게 된 이유는 다음과 같습니다. 왜 shared_ptr입니까? 과장된 것 같아요 –

+0

shared_ptr는 개체 복사본 수를 1로 줄입니다. 유스 케이스에 따라 다르지만 필요하지 않을 수도 있습니다.포인터는 단지 움직일 때 더 빠릅니다. 문자열 객체 (기본 체인의 사본 포함)가 아닙니다. 문자열이 짧으면 아마도 과잉 공격 일 것입니다. –

1

(예를 들어 s.c_str()에서 포인터가) 너무 조심 그런 물건들.

map<pair<const char*, const char*>, string&> m; 

이드 그런 구조가 매우 위험한 생각, 난 당신이 키가 문자열을 기반으로 비교를 찾기 위해 기대 예를 들어 가정, 문자열 (즉, poitner 값)의 위치가 아닌.

그러나 키 선택을 무시하고 m_tmp 값을 사용하는 것이 안전하고 잘 정의되어 있습니다 (즉, "동일한"변수가 있기 때문에 하나를 변경하면 다른 문자열이 변경됩니다). "m_tmp string; " 범위를 벗어나면 (또는 삭제 된 경우) 맵을 통해 액세스하려고 시도합니다 (더 이상 유효한 메모리를 참조하지 않기 때문에).

예 : 다음은 안전하지 않습니다.

std::map<int, string &> myMap; 
void foo() 
{ 
    string s = "Hello World"; 
    myMap[5] = s; 
} 
int main() 
{ 
    foo(); 
    //string s was destroyed when foo() returned, so myMap[5] is no longer a valid reference, 
    //so it is not defined what will happen here, hopefully an access violation 
    //rather than some obscure bug because the stack/heap got corrupted 
    std::cout << myMap[5] << std::end; 
} 

그것의 요소는 (그러나 성병 : :지도가 무효화 할 수있는 유일한 시간 이잖아 삭제되지에서 참조를 가지고 있음을 다시 한번, 만약 당신이 다른 방법으로 할 수있는 것을주의 제공도 가치 참조 또는 반복자).

std::map<int,string> myMap; 
myMap[5] = "x"; 
string &s = myMap[5];//get a referecnce 
myMap[5] = "Foo"; 
std::cout << s << std::end;//print Foo 
s = "Bar"; 
std::cout << myMap[5] << std::endl;//print Bar 
+0

좋아요. 문제는 가 아니라 문자열 &입니다. 이전의 경우,이 쌍으로 변경할 수 있습니다. ... 실제로 제가 추천 한 내용을 기반으로합니다. –

+0

인스턴스의 멤버를 참조 할 때 & string 문자열이 파괴되지 않습니다. –

+0

그러면 안전하다고 말했고, 변경하면 다른 하나가 바뀔 것입니다. –

0

유형을 제한하지 않는 한 문자열 &을 직접 수행하는 대신 다른 클래스에 문자열을 래핑하는 것이 좋습니다. 약간의 오버 헤드가 있지만 그 이유를 철저히 설명 할 수있는 공간을 제공합니다. 변경 가능성, 코드를 의미에 대해 좀 더 분명하게 만듭니다.

지옥은 원하는 경우 ReassignableString이라는 유일한 멤버를 공개 문자열로 사용하는 클래스로 만듭니다.