2010-06-03 3 views
6

그래, previous 질문에 분명히 대답했지만 다른 문제를 발견했습니다.C++ new & delete and string & functions

내가 할 경우 :

char *test(int ran){ 
    char *ret = new char[ran]; 
    // process... 
    return ret; 
} 

를 그리고 그것을 실행

for(int i = 0; i < 100000000; i++){ 
    string str = test(rand()%10000000+10000000); 
    // process... 

    // no need to delete str anymore? string destructor does it for me here? 
} 

그래서 문자열로의 char *로 변환 후, 나는 더 이상 삭제에 대해 걱정할 필요가 없습니다?

편집 : 어떻게 제대로 문자열로 문자 변환을 수행합니다으로, 나는 delete[]new[] 전화를 가지고 있지만, 포인터가있어 손실 이후 질문은 그래서 내 경우에, 불가능의 대답?

+0

Re : 편집 중 ... 포인터를 잃어 버리거나 (더 좋은 방법은) 포인터를'new'하지 말고 그냥'std :: string'을 사용하여 문자열을 유지하십시오. 왜 스스로 메모리 할당을하고 싶습니까? – Johnsyweb

답변

9

당신은 [std::]stringchar* 변환하지 되어 있지만 [std::]string-복사char*.

일반적으로 new마다 delete이어야합니다. 이 완료되면이 경우

, 당신은 포인터의 복사 및 delete 보관해야합니다 :

char* temp = test(rand()%10000000+10000000); 
string str = temp; 
delete[] temp; 
+0

그럼 어떻게 제대로 char을 string으로 변환합니까? – Newbie

+0

'char *'를'std :: string'으로 변환하라는 말을 들었을 때,'char *'대신에 **'std :: string'을 사용해야한다는 의미였던 것 같습니다. 프로그래밍 방식으로 – Johnsyweb

+0

이렇게하는 간단한 방법이 있습니까? 어떤 종류의 함수 또는 무언가와 마찬가지로 코드 한 줄만 필요합니까? – Newbie

2

예, 가능합니다.

당신이 리눅스/OS X의를 사용하는 경우, 메모리

를 발행으로 대신 char *string을 반환하도록 당신은 당신의 테스트 기능을 변경할 수 있습니다 당신을 도울 수 valgrind 같은으로 당신이 delete [] ret을 할 수있는이 방법을 보면 테스트 기능에서.

또는 테스트에서 문자열을 사용하면 새롭거나 삭제되는 것에 대해 걱정할 필요가 없습니다. 여기

+0

그래서 나는 사용해야한다 : delete [] str; ? – Newbie

+0

아니요, str은 자체 개체입니다. 이 경우 할당 한 새 char []에 대한 포인터를 잃어 버렸기 때문에 삭제할 수 없으므로 메모리 누수가 발생합니다. –

3

당신은 impresison 아래로 보이는 그 표준에 char*을 통과 :: 문자열은 할당 된 메모리의 소유권을 전송합니다. 실제로 그것은 단지 사본을 만듭니다.

이 문제를 해결하는 가장 쉬운 방법은 함수 전체에 std :: string을 사용하여 직접 반환하는 것입니다. 모든 new에 대한

std::string test(int ran){ 
    std::string ret; 
    ret.resize(ran - 1); // If accessing by individual character, or not if using the entire string at once. 
    // process... (omit adding the null terminator) 
    return ret; 
} 
+0

char * 생성의 중간 단계를 건너 뛰는 경우 +1. 즉, 예제 코드에 이름이 없습니다 ... –

2

당신 해야 전화 delete 그렇지 않으면 당신은 메모리 누수가됩니다. 포인터를 버리고있는 경우에는 char*을 반환하는 함수를 그대로 두어야하며 std::string을 만들려면 두 줄을 사용해야하므로 을 delete에 복사 할 수 있습니다.

보다 나은 해결책은 test() 함수를 다시 작성하여 std::string을 직접 반환하는 것입니다.

2

당신은 같은 것을 할 필요가 :

for(int i = 0; i < 100000000; i++){ 
    int length = rand()%10000000+10000000; 
    char* tmp = test(length); 
    string str(tmp); 
    delete[length] tmp; 
} 

이 제대로 할당 된 문자 배열을 삭제합니다.

그런데 이런 식으로 만들면 (즉, test 함수 안에서) 문자열을 항상 0으로 종료해야합니다. 그렇지 않으면 일부 기능이 쉽게 "혼란스러워"쉽게 문자열의 일부로 취급 할 수 있습니다. 가장 좋은 경우에는 응용 프로그램이 충돌하고 최악의 경우 궁극적 인 디버깅 악몽 인 나중에 정의되지 않은 동작으로 이어지는 자동 버퍼 오버플로가 발생합니다 ...;)