After a string is created, functions that may grow the string, such as
append()
and insert()
, will cause a buffer reallocation to
occur if the buffer becomes to small to fit the new string. If you
suspect this is going to happen, you can make things a bit more efficient by
resizing the string buffer yourself ahead of time. As an example, let create a
function that appends random characters to a string. One way to do this is:
void appendRandom(Str& str, unsigned int num_chars) { char* x = " "; for (int i=0; i<num_chars; ++i) { x[0] = (rand() & 0x7F) + 1; str.append(x); } }
The problem is that, if num_chars
is large, a lot of buffer
reallocation can take place. Setting str
to be TIME_EFFICIENT
is
one way to solve the problem but, in this particular case, there is a
better way.
void appendRandom(Str& str, unsigned int num_chars) { char* x = " "; str.resize(str.length() + num_chars + 1); for (int i=0; i<num_chars; ++i) { x[0] = (rand() & 0x7F) + 1; str.append(x); } }
The call to resize()
ensures that str
's buffer is large enough to hold the new data
before the append operations begin. Note that, by default,
resize()
will not shrink a buffer, only grow it. This means
that, if a different function already made the string large enough or if the
string was based on a large stack or statically-allocated buffer, the resize()
above would have no effect.
But what if you want to reduce string memory usage? By passing a second
parameter of true
(i.e. resize(32, true)
, a programmer
can force a string to reallocate a smaller buffer.
Along these lines, a programmer can call also call compact()
on a
string. The compact()
function simply calls resize(length() + 1, true)
.
This is useful for reclaiming a large, empty string buffer.
Note that, for efficiency, compact()
and resize(x,true)
are the
only two functions that reduce the buffer size of a string. Also note
that calling compact()
or resize(x,true)
on a string that
is using stack or statically-allocated data will cause the string to switch to heap
data. For this reason, it is a usually good idea to avoid calling these
functions on stack and statically-allocated strings.
To make the rules perfectly clear, here is the resize()
logic restated:
resize()
will only resize the buffer to grow it
compact()
, Str
functions always call
resize()
using default options.
resize()
does resize a buffer, whether it be due to growing
the buffer or a manual override, the new buffer will be created on the heap.
If, during buffer reallocation, STR_ALLOCATED
is set then the old
buffer data will be deallocated with free()
. If STR_ALLOCATED
is clear, as it should be for stack and statically-allocated data, the old buffer data is
not deallocated but is no longer connected to the string. In either case,
STR_ALLOCATED
will be set when the buffer [re]allocation has completed.
length()
, the string is
truncated, even if the buffer size is not actually changed. This is not the
best way to truncate a string, however. Use cut()
instead.