Как скопировать содержимое переменной типа const char*?

Я знаю разницу между:

char *a = "string";
char p[] = "string";

С *a, оно действует следующим образом...

     +-----+     +---+---+---+---+---+---+---+ 
  a: |  *======> | s | t | r | i | n | g | |    
     +-----+     +---+---+---+---+---+---+---+ 

если я хочу создать другую переменную, скажите

char *b;

и я надеюсь, что он копирует все содержимое в указатель a указывает, а не указывает на содержимое A.

     +-----+     +---+---+---+---+---+---+---+      
  a: |  *======> | s | t | r | i | n | g | |    
     +-----+     +---+---+---+---+---+---+---+ 
  b: |  *======> | s | t | r | i | n | g | |    
     +-----+     +---+---+---+---+---+---+---+ 

как это сделать ?

5 ответов


В C++, вы можете сделать

char *b = new char[strlen(a) + 1]{};
std::copy(a, a + strlen(a), b);

здесь живой пример. Хотя, я бы рекомендовал использовать std::string для своих безопасности и простоты в использовании.


в C вы можете выделить новый буфер b, а затем скопировать строку туда со стандартными библиотечными функциями, такими как:

b = malloc((strlen(a) + 1) * sizeof(char));
strcpy(b,a);

Примечание +1 на malloc чтобы освободить место для завершения ''. The sizeof(char) избыточно, но я использую его для согласованности.

в C++ вы должны использовать более безопасный и элегантный std::string:

std::string b {a};

, Как вы опубликовали, указывает на расположение памяти только для чтения, настроенное компилятором. Если вы хотите иметь еще один во время компиляции с различными значениями, вам придется определить его самостоятельно:

char *a = "string";
char *b = "string"; // Nb. This might point to the same location as a

обратите внимание, что в соответствии с §2.14.5, будут ли эти два указателя указывать или нет на одно и то же место памяти реализации

все ли строковые литералы различны (то есть хранятся в неперекрывающихся объекты) определяется реализация.

в противном случае перейдите в место хранения кучи, например:

size_t len = strlen(a); // Doesn't include null-terminator character
char *b = new char[len+1];
memcpy(b, a, len); // Assumes plain ASCII string
b[len] = '';

Я бы пошел на std::strings в любом случае.


вы можете использовать нестандартные (но доступные во многих реализациях)


содержание a это то, что вы обозначили как * на диаграмме. a это ваш маленький ящик, и содержимое a есть то, что в коробке!

"строка" не является содержимым a. Это где-то еще в памяти, и a содержит адрес этой строки.

копирование содержимого a to b в конечном итоге это сделает:

   +-----+     +---+---+---+---+---+---+---+      
a: |  *======> | s | t | r | i | n | g | |    
   +-----+  /  +---+---+---+---+---+---+---+ 
b: |  *====/
   +-----+     

чтобы достичь того, что вы нарисовали на своей второй диаграмме, вы нужно взять копию всех данных, которые a указывает на. Это не просто, потому что как вы решаете, когда прекратить копирование? Нет общего способа, но если вы предопределили, что вы просто хотите скопировать строку, вы можете использовать функцию, которая копирует строку.

общие, но нестандартное