Подтвердить что ты не робот

Как скопировать char * в строку и наоборот

Если я передам char * в функцию. Я хочу, чтобы этот char * преобразовал его в std::string, и как только я получу свой результат, верните его обратно в char * из std::string, чтобы показать результат.

  • Я не знаю, как это сделать для преобразования (я не говорю const char *, а просто char *)
  • Я не уверен, как манипулировать значением указателя, который я отправляю.

поэтому мне нужно сделать шаги

  • возьмите char *
  • преобразует его в строку.
  • возьмите результат этой строки и верните ее в виде char *
  • возвращает результат таким образом, что значение должно быть доступно вне функции и не будет уничтожено.

Если возможно, я могу увидеть, как это можно сделать с помощью ссылки против указателя (адрес которого я передаю по значению, но я все же могу изменить значение, на которое указывает указатель. Поэтому, даже если копия адреса указателя в функция уничтожается, я все еще вижу измененное значение снаружи.

спасибо!

4b9b3361

Ответ 1

Преобразование a char* в std::string:

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

Преобразование a std::string в 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;

Я предпочитаю использовать std::vector<char> вместо фактического char*; то вам не нужно управлять собственной памятью:

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];

Ответ 2

Вам нужно посмотреть, как вы обрабатываете память из возвращаемого указателя, например, код ниже не будет работать, потому что память, выделенная в std::string, будет выпущена, когда fn() выйдет.

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

Одно из решений - выделить память в функции и убедиться, что вызывающая функция освобождает ее:

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

В качестве альтернативы, если вы знаете верхнюю границу размера строки, вы можете сами создать ее в стеке и передать указатель, например.

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)

Ответ 3

Вы можете сохранить сборщик мусора для своей библиотеки, реализованный как std::vector<char*> g_gc;, доступный в вашей библиотеке lib. Позже вы можете освободить все указатели в g_gc в удобное для вас время, вызвав 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 будет выглядеть так:

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

В однопоточной модели вы можете сохранить этот статический файл g_gc. Многопоточная модель будет включать блокировку/разблокировку.