2010-07-30 7 views
2

이것은 C++ 코드에 관한 메모리 관리 질문입니다.메모리 관리

using namespace std; 
#include <iostream> 
#include <string.h> 

int main() 
{ 
string a="first"; 
string *b= new string; 
*b=a; 
a="second"; 
cout << *b << ", " << a; 
delete b; 
return 0; 
} 

b가 가리키는 문자열을 저장 한 메모리 블록을 할당 해제 할 수 있습니다. 이 작업이 완료되면 b가 더 이상 의미가 없음을 의미합니다. 일부 메모리를 비우려면 b를 할당 해제 할 수 있습니다. 왜 우리는 할당을 해제 할 수 없습니까? 포인터를 삭제할 수는 있지만 문자열 A는 어딘가에 메모리를 차지해야한다는 것을 알고 있습니다. 문자열 a가 차지하는 메모리를 해제 할 수있는 방법이 있습니까? a가 초기화되는 것과 같은 방법으로 초기화 된 문자열이 충분한 경우 메모리가 부족할 수 있습니까?

답변

0

에 할당 된 메모리가이면 함수가 반환 된 후 자동으로 해제됩니다.

4

문자열 a이 스택에 선언됩니다. 수동으로 해제 할 수는 없지만 범위를 벗어나면 자동으로 해제됩니다 (예 : 둘러싸는 함수가 반환 될 때). 그 메모리 중간 기능을 해제 할 수 있어야한다면, 동적으로 선언하십시오 (예 : b).

+0

+1 당신의 대답은 내 것이 더 완전합니다. – karlphillip

+0

또는 문자열을 작은 범위로 묶을 수 있습니다 ... 대부분의 경우 가치가있는 것은 아닙니다. –

2

자동 개체 (예 : a)는 범위를 벗어날 때 파괴됩니다. 아래의 예를 참조하십시오

int main() 
    { 

    { 
    string a="first"; 
    string *b= new string; 
    *b=a; 
    a="second"; 
    cout << *b << ", " << a; 
    delete b; //b gets freed 
    } //a gets freed because it has gone out of scope 
/* You can write more code here that does not need a */ 
return 0; 

}

여기
0

a가 자동으로 "스택"을 할당하고,이 범위를 벗어나면 자동으로 해제/파괴됩니다.

동적 메모리를 new/malloc과 함께 사용하면 프로그램에서 사용할 수있는 메모리 뭉치 인 "힙"에 할당됩니다. 이를 수동으로 관리해야하며 프로그램은 언제 제거해야하는지 알지 못합니다.

이 경우 실제로 메모리가 걱정된다면 동적 메모리 할당 만 사용해야합니다.

편집 : 문자열은 그 수명에 의해 관리되는 문자열 데이터의 저장에 대한 포인터를 포함하는 작은 물체로 구성 http://en.wikipedia.org/wiki/Malloc#Rationale

3

:이 내가 말하려고하는 것보다 더 완전한 설명을 제공 목적. 일반적으로 객체 자체가 차지하는 메모리는 걱정할 필요가 없지만 문자열이 큰 경우 객체를 손상시키지 않고 저장소를 비울 수 있습니다.

clear()을 호출하거나 emptry 문자열에서 할당하면 저장소를 비울 수 없습니다. 그것이 해제되었는지 확인하는 방법은 새로 생성 된 임시 문자열을 문자열로 바꾸는 것입니다. 임시의 소멸자가 그것을 해제합니다.

string().swap(a); // replaces `a` with an empty string 

표준 컨테이너로도이 작업을 수행 할 수 있습니다.

3

이것은 다소 서툴 릅니다.

<string.h>은 C 헤더입니다. string을 정의하지 않습니다. <iostream> 버전에 직접 또는 간접적으로 <string>이 포함되어 있거나 오류가있는 것으로 보입니다.

리터럴 문자열 (쌍 따옴표로 묶인 것)은 읽기 전용 메모리 세그먼트를 포함하여 거의 모든 위치에있을 수 있습니다. (그들은 메모리를 차지하지만 큰 영향을 끼칠 텍스트가 많습니다. 전쟁과 평화은 완전한 메기를 차지하지 않습니다.)이 경우 std::string은 이 값으로 초기화되고 나중에 다른 값이 할당됩니다. std::string은 사용하는 메모리를 처리합니다.

C++에서 std::string에 대한 포인터를 가질 이유가 거의 없습니다. std::string은 내용이 없으면 공간을 많이 차지하지 않으며 내용 자체의 메모리를 관리합니다. 이걸 char *과 혼동하고 있습니까?

newstd::stringb에 대해 b에 다른 주소를 할당하면 메모리가이되지 않습니다. 그것은 메모리 누수입니다. 무엇 new에 대한 b에 대한 에드 여전히 할당되어 있지만 거기에 방법이 없습니다 delete, 그래서 그것은 프로그램의 기간 동안 메모리를 차지할 것입니다.

그런 다음 a의 주소를 b에 할당하면 delete b;입니다. 이것은 나쁜 생각이며 아마도 예측할 수없는 방식으로 중요한 것을 엉망으로 만들 것입니다. new으로 획득 한 메모리는 delete입니다. (delete ing의 중요한 점은 b은 포인터이므로 삭제해야하지만, 가리키는 메모리는 new을 통해 얻지 못했습니다.

메모리 관리는 이와 비슷한 방식으로 작동합니다. 문자열 리터럴은 어딘가에 할당됩니다. 당신이 아는 한 당신은 그것을 바꾸려고 시도해서는 안되며, 어떠한 수단으로도 delete 그것을 시도하면 안됩니다. 값을 사용하고 나머지는 만지지 마십시오. std::string은 자체 내용의 메모리를 관리하며 소멸자에서 처리합니다. 함수 또는 다른 블록에서 선언 된 변수는 일단 범위를 벗어나면 소멸됩니다 (포인터가 스마트 포인터이거나 자체 메모리를 관리하는 경우에만 포인터가 가리키는 포인터는 자동으로 소멸되지 않습니다). new 메모리 인 경우 delete d가 될 때까지 포인터 값을 버리지 마십시오. new 메모리가 없으면 delete이 아닙니다.

+0

+1 코드에 대한 자세한 설명은 +1을 참조하십시오. – rturrado

+0

흠 실제로 메모리 누수가 없습니다. 작성자는 작성했습니다 'string * b = new string; * b = a; ' 그가 쓰면 메모리 누출이 발생합니다 : ' string * b = new string; b = & a; ' 다른 진술에 동의 해주세요. – Haspemulator

+0

+1 문자열 리터럴 메모리 위치를 언급합니다. 일반적으로 스택이나 힙이 아닌 응용 프로그램의 정적 메모리에 있습니다. 따라서 문자열 리터럴에 대한 포인터를 절대로 삭제하면 안됩니다. – Zoomulator