yabansu

Hi everyone,

I have a problem in returning an unsigned char* from a function.

In the main function:

string name = "yabansu";
unsigned char* arr1 = (unsigned char*) name.c_str();
cout << arr1 << endl;   //Correctly prints "yabansu"

Let's say I wrote a function called StringToBytes for doing the same thing above as the following:

unsigned char* StringToBytes(string s)
{
    cout << (unsigned char*) s.c_str()     //Correctly prints "yabansu"
    return (unsigned char*) s.c_str();
}

Then I call this function in the main() as below;

string name = "yabansu";
unsigned char* arr2 = StringToBytes(name);
cout << arr2 << endl;   //prints weird characters instead of "yabansu"

As you see, nothing is different and the string("yabansu") can be properly displayed within the StringToBytes() function.

What could be the reason Thanks...


Re: Visual C++ Language Cannot properly return unsigned char*...

Marius Bancila

Are you sure this is the code I have the feeling you are returning a pointer to a local variable, that goes out of scope as soon as the function returns.

unsigned char* StringToBytes()
{
  string s("yabansu");
  cout << (unsigned char*) s.c_str()   //Correctly prints "yabansu"
  return (unsigned char*) s.c_str(); // error, you return the address of a buffer that is release as soon as the function returns
}






Re: Visual C++ Language Cannot properly return unsigned char*...

yabansu

Hi Marius,
Is there a way to solve such a problem There can be lots of C++ tricks that I do not know.
Briefly, I want a function that returns the unsigned char* of a string which is taken as a parameter. Do I want too much
Thanks...





Re: Visual C++ Language Cannot properly return unsigned char*...

einaros

If you *need* to return the char pointer, you will have to do three changes to your code

  1. The return type of StringToBytes has to be const unsigned char*. The internal char buffer of the string class must not be touched.
  2. StringToBytes must take a reference to a string, not a copy of a string, as its parameter. If you pass by value (which means a copy string is created when the function call begins, and destroyed when the call returns), the pointer returned from the function will no longer point to meaningful data.
  3. The string passed to StringToBytes must exist for as long as the char pointer returned is used. Once this string has been removed, the pointer will no longer (as above) point to meaningful data.

An example:

const unsigned char* StringToBytes(string& s)
{
cout << (unsigned char*) s.c_str() //Correctly prints "yabansu"
return (unsigned char*) s.c_str();
}

string s = "....";
const unsigned char* c = StringToBytes(s);

As I'm sure you can see, this is not a very robust approach. You would be far better off returning a string, or even better a vector of unsigned char's, such as:

vector<unsigned char> StringToBytes(string& s)
{
cout << (unsigned char*) s.c_str() //Correctly prints "yabansu"
return vector<unsigned char>(s.begin(), s.end());
}

string s = "....";
vector<unsigned char> v = StringToBytes(s);

The morale of the story: don't use native pointers if the STL has something better to offer.






Re: Visual C++ Language Cannot properly return unsigned char*...

Marius Bancila

yabansu wrote:

Hi Marius,
Is there a way to solve such a problem There can be lots of C++ tricks that I do not know.
Briefly, I want a function that returns the unsigned char* of a string which is taken as a parameter. Do I want too much
Thanks...

Duh, stupid me. Your code did not work correctly because you passed the string by value. Than means a copy is made in the functions stacks, so that one goes out of scope, and the memory it holds is released when the function returns.

So, you have to follow einar's indication, and pass the parameter by reference.






Re: Visual C++ Language Cannot properly return unsigned char*...

yabansu

Hi einaros,

I understood it very well.. Thanks for the explanations..
After I changed the string passing method from value to reference, it worked!
It worked, even I did not change the return type...
I would like to use vector also, but the methods in the encryption libraries I use, accept pure unsigned char[] as inputs, so it is not a better choice in this case. Isn't it





Re: Visual C++ Language Cannot properly return unsigned char*...

einaros

yabansu wrote:

I would like to use vector also, but the methods in the encryption libraries I use, accept pure unsigned char[] as inputs, so it is not a better choice in this case. Isn't it

That's the beauty of vector -- you can feed it to API's which expect native arrays.

void myOldFunction(unsigned char* input)
{
}

string str = "hello world";
vector<unsigned char> v(str.begin(), str.end());
myOldFunction(&v.front());






Re: Visual C++ Language Cannot properly return unsigned char*...

yabansu

einaros!

Thanks for showing us the beauties of the vectors. I really liked them!