Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ memcpy to char* from c_str

I've done a bit of basic reading and from what I've gathered .c_str() always has a null terminator.

I have a fairly simple C++ program:

int main(int argc, char** argv)
{
  std::string from = "hello";
  char to[20];
  memcpy(to, from.c_str(), strlen(from.c_str())+1);
  std::cout<< to << std::endl;
  return 0;
}

Will that memcpy ensure that I copy over a null-terminated string to my variable to (provided that my string from is shorter in length)?

like image 688
Max Avatar asked Jul 11 '13 06:07

Max


People also ask

What is string c_str ()?

The basic_string::c_str() is a builtin function in C++ which returns a pointer to an array that contains a null-terminated sequence of characters representing the current value of the basic_string object.

Does c_str add null terminator?

c_str returns a "C string". And C strings are always terminated by a null character. This is C standard. Null terminating strings.

Can you memcpy a string?

This C string library function memcpy( ) copies n characters from the block of memory pointed by str1 to str2 . It returns a pointer to the block of memory or object where contents are copied. Note: The pointers are declared as void * so that they can be used for any data type.

What is std memcpy?

std::memcpy is meant to be the fastest library routine for memory-to-memory copy. It is usually more efficient than std::strcpy, which must scan the data it copies or std::memmove, which must take precautions to handle overlapping inputs.


3 Answers

memcpy doesn't know what is a string. you give it a range to copy. it depends on strlen here to provide the termination point of range

like image 61
Neel Basu Avatar answered Oct 26 '22 15:10

Neel Basu


You should use std::string to copy strings. However, if you want to do it like that you should use strcpy instead of memcpy

int main(int argc, char** argv)
{
  std::string from = "hello";
  char to[20];
  strcpy(to, from.c_str());
  std::cout<< to << std::endl;
  return 0;
}
like image 29
ronag Avatar answered Oct 26 '22 15:10

ronag


Yes, this will work as long as your string in from is shorter than 20. Oh, no, wait, we are also copying the NULL terminator so it must be shorter than 19. I guess you see how that can lead to some confusion.

Which is by the way exactly the reason why this code is dangerous: I am assuming this is demo code and your actual code will get that string from some sort of input. At that moment you will not be able to control how long it is. You can truncate it but you might forget to do that which means that your program will be copying content to memory that possibly does not belong to it. This might lead to a crash but at least to undefined behaviour as you are overwriting memory that might contain other important data.

Using the string class actually helps to avoid such problems by not having to specify the string length. I would suggest using this class and only do operations involving c_str() when absolutely necessary.

like image 37
Chris Avatar answered Oct 26 '22 15:10

Chris