2012-04-19 6 views
0

이 빨리 가능한 한 간결하게하려면이 내 코드입니다 :문자 배열의 내용을 변경할 수 있습니까?

char* aiMove = getAIMove(); 
    cout << aiMove; 
    cout << "\n" << numMoves << ": " << aiMove << "\n\n"; 
    return aiMove; 

그리고 이것은 내 출력 :

a0 a1 
    0: �����������������������7 

그래서, 첫 번째 줄 getAIMove을 (호출) 및 반환을 할당 value (char *)를 aiMove로 변경하십시오.

두 번째 줄은 aiMove (a0 a1)를 인쇄합니다.

세 번째 줄은 numMoves 및 aiMove를 cout으로 가져 와서 인쇄하지만 일부 이상한 값을 대신 인쇄합니다.

4 번째 줄은 aiMove를 반환하며, 이상한 값으로 인쇄되도록 검사했습니다.

왜 aiMove 값이 변경 되었습니까? 이것은 cout에 정수 값을 전달할 때만 발생하는 것으로 보입니다 (이 경우 numMoves).

도와주세요! 감사합니다, 패트릭 :

편집 : 내가 얘기를 깜빡 했네요 또 다른 한가지는 코드 블록이 처음으로 실행됩니다 때이 이상한 행동은 발생 즉, 프로그램 동안 실행됩니다 때마다 다음 시간이 인쇄 벌금.

+4

getAIMove() is char * getAIMove() {char str [] = "Patrick"; return str; } ??? 그렇다면 로컬 변수에 대한 포인터를 반환하는 것은 잘못된 것입니다. – Jagannath

+5

getAIMove() 코드를 제공 할 수 있습니까?할당 된 로컬 스택을 반환합니까? –

+0

@ Jagannath 맞아, getAIMove()가 결국 char str []을 반환합니다. 고마워. 왜 아직도 정수 값을 cout에 건네 주면 이해가 안되지만 S –

답변

3

getAIMove이 시스템에서 다시 사용할 수있는 메모리 포인터를 반환했음을 분명히 나타냅니다. 스택이나 힙에서 후속 할당이 반환 된 포인터를 덮어 씁니다.

이 일어날 수있는 많은 방법이 있습니다, 이것은 가장 일반적인 아마도 :

char *GetAIMove() 
{ 
    char buf[128]; 
    strcpy(buf, "a0"); 
    strcat(buf, " "); 
    strcat(buf, "a1"); 
    return buf; // oops, buf won't exist after we return 
} 

아차. 이 코드는 반환 할 때 즉시 존재하지 않는 버퍼에 대한 포인터를 반환합니다. 이 문제의 일반적인 해결 방법은 return strdup(buf);입니다. 함수의 호출자는 문자열을 처리 할 때 문자열을 해제해야한다는 것을 기억하십시오. 이것에 대한

std::string GetAIMove() 
{ 
// ... 
return foo; 
} 

char* aiMov e= GetAIMove(); 
// aiMove points to the contents of the returned string, no longer in scope. 

수정이 std::string aiMove = GetAIMove입니다 :

는 여기에 또 다른 방법입니다. 이제 aiMove은 문자열을 범위로 유지합니다.

그러나 가장 좋은 수정 구체적를 통해 문자열을 끝까지 유지하기위한 문자열 클래스를 사용하는 것입니다

std::string GetAIMove() 
{ 
    std::string foo; 
    foo = "a1"; 
    foo += " "; 
    foo += "a2"; 
    return foo; 
} 

std::string aiMove = GetAIMove(); 

참고이 코드가 실제로 복사를 많이 포함하는 표시되는 동안, 현대 컴파일러는 것 효율적으로 만드십시오. 따라서 코드를 단순하고 논리적이며 이해하기 쉽고 유지하기가 어렵다고 생각하지 마십시오.

+0

깊이있는 설명 주셔서 감사합니다! :) getAIMove()가 std :: string을 반환하도록 설정 한 다음 다음과 같이하면 좋을까요? char * aiMove = getAIMove(). c_str(); ? –

+0

아니요. 문자열에 대해 호출 된 비 const 메서드는 반환 된 포인터를 무효화하고 소멸자는 비 const입니다. 그래서 다시'aiMove'는 더 이상 존재하지 않는 무언가의 내용을 가리킬 것입니다. [c_str] (http://www.cplusplus.com/reference/string/string/c_str/)에서 반환 된 포인터는 문자열을 수정할 수있는 작업이 완료 될 때까지만 유효합니다. 그것을 파괴하는 것은 확실히 자격이됩니다! –

0

아니요, cout은 매개 변수의 내용을 변경하지 않습니다.

아마도 당신은 이미 뭔가 잘못하고 정의되지 않은 동작을하고있을 것입니다.

관련 문제