2013-03-24 1 views
1

const char *에서 NSString을 가져 오는 중 이상한 버그가 발생했습니다.const char *를 NSString으로 변환하려고 할 때 빈 문자열

// in my obj c class 
void myObjCMethod { 
    const char* charString = myCFunctionReturningConstCharPtr(); 
    printf("%s \n", charString); // prints the correct string 

    // ...put a brakpoint here... 

    NSString * nsString1 = [NSString stringWithUTF8String:charString]; 
    NSLog(@"%@", nsString1); // prints nothing 

    NSString * nsString2 = [NSString stringWithFormat:@"%s",charString]; 
    NSLog(@"%@", nsString2); // prints nothing either 
} 

내 c 메서드에서 오는 const char이 콘솔에 멋지게 인쇄됩니다. 하지만 NSString으로 변환하려고하면 빈 문자열이됩니다. 이상한 점은, 코드를 디버깅하고 (위에 표시된 바와 같이) 중단 점을 설정하려고하면 NSString이 갑자기 으로 유효하게됩니다!

그래서 내 측정치가 결과를 변경합니까? 오래 전에 물리학 수업에서 익숙한 것 같지만 여기에는 양자 역학이 관련되어 있습니다.

주 : 아마 본 문제와 관련이없는 복잡성의 또 다른 레이어를 추가하는 것처럼 내가 지금 myCFunctionReturningConstCharPtr()의 구현을 생략 한

이 (관련된 여러 C++ 라이브러리가 있으며, 문자열은 변환 된 char 포인터에서 std :: string 및 back).

나는 2 일 동안 내 머리를 두드리는 소리가났다. 어떤 도움이라도 대단히 감사한다. 감사합니다

편집 :

캐릭터는 처음에 파워 VR의 내부자 SDK에서 구조체 SPODNode에서 온다. 이 우리가 내 코드에서

typedef char PVRTchar8; 

내가 할 :

struct SPODNode { 
    PVRTchar8 *pszName; 
    // ... 
} 

으로

std::string MyCppClass::pvrNodeName() { 
    if (node && node->pszName) { 
     string stdName(node->pszName); 
     return stdName; 
    } 
    return string(); 
} 

그리고 마지막으로 myCFunctionReturningConstCharPtr()에서 :

const char * myCFunctionReturningConstCharPtr() { 
    std::string stdString = myCppClassInstace->pvrNodeName() 
    return stdString.c_str(); 
} 

을 나는 희망이 도움이 !

+1

나는'myCFunctionReturningConstCharPtr을 (의심 것 :

당신은 (가치에 의하여) 함수 반환 std::string을 가지고, 당신은 캡슐화 된 C-문자열을 얻을 필요가있는 경우 그 반환 값에 c_str()를 호출한다 . 그것을 보여줄 수 있습니까? –

+0

쉽지는 않지만 코드가 너무 복잡합니다. 나는 그것을 무너 뜨리고 그것을 나의 질문에 추가하려고 노력할 것이다. 주어진 예제가 그 자체를 의미하기를 바랬습니다. –

+0

'const char *'가 반환되는 방식에 관심이 있습니다. 특히'data()'또는'c_str()'을 호출하여 로컬'std :: string' 객체로부터 얻을 수 있는지 여부. –

답변

4

const char *는 std :: string에서 .c_str()을 호출하여 가져옵니다. 이 기능 myCFunctionReturningConstCharPtr()에서 반환 할 때 해제됩니다 문자의 배열에 대한 포인터를 반환하기 때문에

당신의 프로그램이 정의되지 않은 동작을 가지고 가능성이 높다.

사실 const char*은 로컬 std::string 개체로 캡슐화 된 문자 배열로 포인트를 반환합니다. std::string 개체의 소멸자는 해당 배열을 할당 해제하고 소멸자는 로컬 개체가 범위를 벗어날 때, 즉 함수에서 돌아올 때 호출됩니다.

나중에받은 포인터를 역 참조하려고하면 정의되지 않은 동작이 발생합니다. 즉, 아무 일도 발생할 수 없습니다. 여기에는 디버깅 중에는 정상적으로 작동하는 것으로 보이는 프로그램이 포함되지만 디버거가 연결되지 않은 상태에서는 실행되지 않습니다.`)

std::string charString = myCFunctionReturningConstCharPtr(); 
printf("%s \n", charString.c_str()); // prints the correct string 
+0

위 업데이트 된 질문의 코드를 참조하십시오. 나의 이해에서 그것은 내가하는 일이다. std 문자열을 c_str()을 사용하여 변환합니다. 결과는 const이며 반환 할 때 여전히 유효해야합니다. 또는 나는 무엇인가 놓치고 있냐? –

+0

@de .: 아니요, 유효하지 않습니다. 내 대답을 쓰는 동안 해당 문자 배열은 로컬'std :: string' 개체가 소유하며 범위를 벗어나면 문자 배열이 삭제됩니다. 내가 제안한 것처럼'const char *'대신에'std :: string'을 반환하십시오. –

+0

알았어. 하지만 내 API는 c, 아니 C++이기 때문에 나는 C로 변환해야합니다. –

관련 문제