c++ - What is the right way to handle char* strings? -
i have third party library using char* (non-const) placeholder string values. right , safe way assign values datatypes? have following test benchmark uses own timer class measure execution times:
#include "string.h" #include <iostream> #include <sj/timer_chrono.hpp> using namespace std; int main() { sj::timer_chrono sw; int iterations = 1e7; // first method gives compiler warning: // conversion string literal 'char *' deprecated [-wdeprecated-writable-strings] cout << "creating c-strings unsafe(?) way..." << endl; sw.start(); (int = 0; < iterations; ++i) { char* str = "teststring"; } sw.stop(); cout << sw.elapsed_ns() / (double)iterations << " ns" << endl; cout << "creating c-strings safe(?) way..." << endl; sw.start(); (int = 0; < iterations; ++i) { char* str = new char[strlen("teststr")]; strcpy(str, "teststring"); } sw.stop(); cout << sw.elapsed_ns() / (double)iterations << " ns" << endl; return 0; }
output:
creating c-strings unsafe(?) way... 1.9164 ns creating c-strings safe(?) way... 31.7406 ns
while "safe" way get's rid of compiler warning makes code 15-20 times slower according benchmark (1.9 nanoseconds per iteration vs 31.7 nanoseconds per iteration). correct way , dangerous "deprecated" way?
the c++ standard clear:
an ordinary string literal has type “array of n const char” (section 2.14.5.8 in c++11).
and
the effect of attempting modify string literal undefined (section 2.14.5.12 in c++11).
for string known @ compile time, safe way of obtaining non-const char*
this
char literal[] = "teststring";
you can safely
char* ptr = literal;
if @ compile time don't know string know length can use array:
char str[str_length + 1];
if don't know length need use dynamic allocation. make sure deallocate memory when strings no longer needed.
this work if api doesn't take ownership of char*
pass.
if tries deallocate strings internally should in documentation , inform on proper way allocate strings. need match allocation method 1 used internally api.
the
char literal[] = "test";
will create local, 5 character array automatinc storage (meaning variable destroyed when execution leaves scope in variable declared) , initialize each character in array characters 't', 'e', 's', 't' , '\0'.
you can later edit these characters: literal[2] = 'x';
if write this:
char* str1 = "test"; char* str2 = "test";
then, depending on compiler, str1
, str2
may same value (i.e., point same string).
("whether string literals distinct (that is, stored in nonoverlapping objects) implementation- defined." in section 2.14.5.12 of c++ standard)
it may true stored in read-only section of memory , therefore attempt modify string result in exception/crash.
they also, in reality of type const char*
line:
char* str = "test";
actually casts away const-ness on string, why compiler issue warning.
Comments
Post a Comment