2017-04-23 4 views
-1

나는 이런 이상한 버크 덕분에 많은 프로젝트를 코딩하지 않아야했다. 나는 바보 같이 보이고 위험해질만큼 위험하다. 그래서 여기에 간다 ...함수에서 C- 문자열을 반환하면 임의의 문자가 나오는 이유는 무엇입니까?

나는 다음과 같은 기능을 썼다.

const char* readFileToString(const char* filename) { 
    const char* result; 
    std::ifstream t(filename); 
    std::stringstream buffer; 
    buffer << t.rdbuf(); 
    result = buffer.str().c_str(); 
    return result; 
} 

나는 기대 file.txtreadFileToString("file.txt")hello 반환해야 함을, hello 포함되어있는 경우, 그. 대신, 그것은 H�rv�0 줄을 따라 왜곡 된 텍스트를 반환합니다. 그러나 반환하기 바로 전에 std::cout << result;을 입력하면 hello이 인쇄됩니다.

C++의 이상하고 불가능한 버클입니까? 어떻게 수정해야합니까?

+3

반환 포인터를 손상되고 그래서 따라서 잘못된 메모리 위치

에 포인트를 초래 거의 좋은입니다 생각. 값으로 반환 된 std :: string을 사용하면됩니다. –

답변

3

이상하지도, 불가능하지도 않습니다. 범위를 벗어난 버퍼 포인터를 반환했습니다. const char*은 문자열 데이터를 "소유"하지 않으며 단지 문자열 데이터를 참조합니다. 또는, 이전까지! 반환 된 포인터는 이제 유효하지 않습니다. 너는 그것을 참조하지 말라.

고급 포인터 기술을 모색하는 대신 std::string을 사용하는 것이 좋습니다.

std::string readFileToString(const char* filename) 
{ 
    std::ifstream t(filename); 
    std::stringstream buffer; 
    buffer << t.rdbuf(); 
    return buffer.str(); 
} 

불행하게도, 나는 여기에 복사를 방지 할 수있는 방법을 알고 아닙니다.

당신은 조금에 대한 설계를 셔플 상관 없어, 당신은 스트림 - 투 - 문자열이 선 아래로 복사 방지 할 수있는 방법이있는 경우, 대신이 작업을 수행 할 수있는 경우 :

void readFileToStream(const char* filename, std::ostream& os) 
{ 
    std::ifstream t(filename); 
    os << t.rdbuf(); 
} 

당신을 스트림의 상태를 나타내는 bool을 반환 할 수 있지만 어쨌든 호출 사이트에서 다시 처리 할 수 ​​있습니다.

1

아래의 해설을 참조하십시오

const char* readFileToString(const char* filename) { 
    const char* result; 
    std::ifstream t(filename); 
    std::stringstream buffer; // Behind the scenes some memory will/is allocated 
    buffer << t.rdbuf();  // Memory is getting filled 
    result = buffer.str().c_str(); // Getting the address of that memory 
    return result; 
    // Buffer getting destroyed along with the allocated memory (what result points to) 
} 

가 .. 여기가 로컬 또는 임시 변수에