1
votes

I have encountered a strange bug while trying to get a NSString from a const char *.

// 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
}

The const char coming from my c method prints nicely to the console. But trying to convert to NSString results in an empty string. Now the weirdest thing is, that when I try to debug the code and set a breakpoint (as indicated above), my NSString suddenly becomes valid!

So what -- my mesurement changes the result? Sounds familiar from physics class long ago, but I doubt there is quantum mechanics involved here.

Note:

I have omitted the implementation of myCFunctionReturningConstCharPtr() for now, as it would add another layer of complexity that is probably not related to the present problem (There are multiple c++ libraries involved, the string has been converted from char pointer to std::string and back).

I've been banging my head against this for two days now, any help is appreciated very much! Thanks

EDIT:

The string initially comes from the struct SPODNode from PowerVR's Insider SDK. There we have:

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

With:

typedef char PVRTchar8;

In my code I do:

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

And finally in myCFunctionReturningConstCharPtr():

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

I hope that helps!

1
I would suspect myCFunctionReturningConstCharPtr(). Could you show it? - Andy Prowl
Not so easy, there's too much code involved. I will try to break it down and add it to my question. I was hoping the given example stands for itself. - de.
I am interested in the way your const char* is returned. In particular, whether it is obtained from a local std::string object through a call to data() or c_str(). - Andy Prowl
Can you at least show the output of the "correct string"? Are there any non-ASCII characters involved? stringWithUTF8String fails if the string is not correct UTF-8. - Martin R
The problem also appears with the string "foo" - de.

1 Answers

4
votes

The const char * is obtained by calling .c_str() on a std::string.

It is very likely that your program has Undefined Behavior, because you are returning a pointer to an array of character that gets deallocated when returning from function myCFunctionReturningConstCharPtr().

In fact, that const char* you return points to a character array that is encapsulated by a local std::string object; the destructor of the std::string object deallocates that array, and the destructor is invoked when the local object goes out of scope, i.e. when returning from the function.

Later attempts to dereference the pointer you receive result in Undefined Behavior, which means anything could happen. This includes your program seeming to run fine when being debugged, but not when running without the debugger attached.

You should have your function return (by value) an std::string, and then invoke c_str() on that returned value if you need to get the encapsulated C-string:

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