Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create string with predefined value and allocated space?

In C, there is a nice construct to create a c-string with more allocated space:

char str[6] = "Hi";  // [H,i,0,0,0,0]

I thought I could do the same using (4) version of string constructor, but the reference says

The behavior is undefined if s does not point at an array of at least count elements of CharT.

So it is not safe to use

std::string("Hi", 6);

Is there any way to create such std::string without extra copies and reallocations?

like image 318
Jan Turoň Avatar asked Oct 17 '25 19:10

Jan Turoň


1 Answers

Theory:

Legacy c-strings

Consider the following snippet:

int x[10];

void method() {
     int y[10];
}

The first declaration, int x[10], uses static storage duration, defined by cppreference as: "The storage for the object is allocated when the program begins and deallocated when the program ends. Only one instance of the object exists. All objects declared at namespace scope (including global namespace) have this storage duration, plus those declared with static or extern."

In this case, the allocation happens when the program begins and freed when it ends. From cppreference.com:

static storage duration. The storage for the object is allocated when the program begins and deallocated when the program ends.

Informally, it is implementation-defined. But, since these strings never change they are stored in read-only memory segments (.BSS/.DATA) of the executable and are only referenced during run-time.

The second one, int y[10], uses automatic storage duration, defined by cppreference as: "The object is allocated at the beginning of the enclosing code block and deallocated at the end. All local objects have this storage duration, except those declared static, extern or thread_local."

In this case, there is a very simple allocation, a simple as moving the stack pointer in most cases.

std::string

A std::string on the other hand is a run-time creature, and it has to allocate some run-time memory:

  • For smaller strings, std::string has an inner buffer with a constant size and is capable of storing small strings (think of it as a char buffer[N] member)
  • For larger strings, it performs dynamic allocations.

Practice

You could use reserve(). This method makes sure that the underlying buffer can hold at least N charT's.

Option 1: First reserve, then append

std::string str;
str.reserve(6);
str.append("Hi");

Option 2: First construct, then reserve

std::string str("Hi");
str.reserve(6);
like image 111
Daniel Trugman Avatar answered Oct 20 '25 07:10

Daniel Trugman