开发者

how to copy char * into a string and vice-versa

If i pass a char * into a function. I want to then take that char * convert it to a std::string and once I get my result convert it back to char * from a std::string to show the result.

  1. I don't know how to do this for conversion ( I am not talking const char * but just char *)
  2. I am not sure how to manipulate the value of the pointer I send in.

so steps i need to do

  1. take in a char *
  2. convert it into a string.
  3. take the result of that string and put it back in the form of a char *
  4. return the result such that the value should be available outside the function and not get destroyed.

If possible can i see how it could be done via reference vs a pointer (whose address I pass in by value however I can still modify the value that pointer is pointing to. so even though the copy of the pointer address in the function gets开发者_开发技巧 destroyed i still see the changed value outside.

thanks!


Converting a char* to a std::string:

char* c = "Hello, world";
std::string s(c);

Converting a std::string to a char*:

std::string s = "Hello, world";
char* c = new char[s.length() + 1];
strcpy(c, s.c_str());

// and then later on, when you are done with the `char*`:
delete[] c;

I prefer to use a std::vector<char> instead of an actual char*; then you don't have to manage your own memory:

std::string s = "Hello, world";
std::vector<char> v(s.begin(), s.end());
v.push_back('\0'); // Make sure we are null-terminated
char* c = &v[0];


You need to watch how you handle the memory from the pointer you return, for example the code below will not work because the memory allocated in the std::string will be released when fn() exits.

const char* fn(const char*psz) {
    std::string s(psz);
    // do something with s
    return s.c_str();   //BAD
}

One solution is to allocate the memory in the function and make sure the caller of the function releases it:

const char* fn(const char*psz) {
    std::string s(psz);
    // do something with s
    char *ret = new char[s.size()]; //memory allocated
    strcpy(ret, s.c_str());
    return ret;
}
....
const char* p = fn("some text");
//do something with p
delete[] p;// release the array of chars

Alternatively, if you know an upper bound on the size of the string you can create it on the stack yourself and pass in a pointer, e.g.

void fn(const char*in size_t bufsize, char* out) { 
    std::string s(psz);
    // do something with s
    strcpy_s(out, bufsize, s.c_str()); //strcpy_s is a microsoft specific safe str copy
}
....
const int BUFSIZE = 100;
char  str[BUFSIZE];

fn("some text", BUFSIZE, str);
//ok to use str (memory gets deleted when it goes out of scope)


You can maintain a garbage collector for your library implemented as std::vector<char*> g_gc; which is accessible in your library 'lib'. Later, you can release all pointers in g_gc at your convenience by calling lib::release_garbage();

char* lib::func(char*pStr)
{
  std::string str(pStr);
  char *outStr = new char[str.size()+1];
  strcpy(outStr, str.c_str());
  g_gc.push_back(outStr); // collect garbage
  return outStr;
}

release_garbage function will look like:

void lib::release_garbage()
{
   for(int i=0;i<g_gc.size();i++)
   {
       delete g_gc[i];
   }
   g_gc.clear();
}

In a single threaded model, you can keep this g_gc static. Multi-threaded model would involve locking/unlocking it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜