Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String management in C++

Tags:

c++

string

I've decided to come back to C++ after some time spent in Java and now I'm quite confused about how strings work in C++.

To start with, suppose we have a function:

void fun() {
   int a = 1;
   Point b(1,2);
   char c[] = "c-string";
}

As I understand, a and b are allocated on the stack. c (the pointer) is allocated on the stack too, but the contents ("c-string") live happily on the heap.

Q1: Are the contents of c automatically deallocated when the function fun ends?

Secondly let's suppose we have a c++ string:

void fun2() {
  (1) string s = "c++ string";
  (2) s += "append";
  (3) s = "new contents";
  (4) s = "a" + s + "c";
}

String documentation isn't too specific about how the strings work, so here are the questions:

Q2: Are the contents of s automatically deallocated after fun2 ends?

Q3: What does happen when we concatenate two strings? Should I care about memory usage? (line 2)

Q4: What happens when we overwrite the contents of a string (line 3) - what about memory, should I worry? Is the originally allocated space reused?

Q5: What if I construct a string like this (line 4). Is it expensive? Are string literals ("a","c") pooled (like in Java) or repeated throughout the final executable?

What I am ultimately trying to learn is how to correctly use strings in C++.

Thanks for reading this,
Queequeg

like image 986
Queequeg Avatar asked Dec 03 '22 02:12

Queequeg


2 Answers

As I understand, a and b are allocated on the stack. c (the pointer) is allocated on the stack too, but the contents ("c-string") live happily on the heap.

That's wrong, they all live in automatic memory (the stack). Even the char array. In C++, a string is an object of type std::string.

Q1: Are the contents of c automatically deallocated when the function fun ends?

Yes.

Q2: Are the contents of s automatically deallocated after fun2 ends?

Yes.

Q3: What does happen when we concatenate two strings? Should I care about memory usage? (line 2)

They are concatenated, and the memory is managed automatically. (assuming we're talking about std::string and not char[] or char*.

Q4: What happens when we overwrite the contents of a string (line 3) - what about memory, should I worry? Is the originally allocated space reused?

Implementation detail. It can be reused, it can be re-allocated if the previous memory can't hold the new contents.

Q5: What if I construct a string like this (line 4). Is it expensive? Are string literals ("a","c") pooled (like in Java) or repeated throughout the final executable?

String literals can be pooled, but it's not required. For large concatenation, it's usual to use a std::stringstream instead (similar to Java). But profile first, don't do premature optimizations. Not that neither of those are string literals though.

char* pStr = "this is a string literal";

This resides in read-only memory and can't be modified.

What I am ultimately trying to learn is how to correctly use strings in C++.

Use a std::string.

like image 88
Luchian Grigore Avatar answered Dec 24 '22 00:12

Luchian Grigore


c is not a pointer. It is an array. You can tell that it's an array because it has square brackets, while pointers have a star. Since c is an automatic variable, it does not require any manual lifetime or memory management.

Ad Q2: s is also an automatic variable, and since it is of a well-designed class type, this means you don't need to take care of anything manually.

Ad Q3: Local string objects are suitably modified to contain the new string; in the process, there may or may not exist temporary string objects for the duration of the concatenation expression. (This applies only to line 4; there's no temporary in line 2.)

Ad Q4: Everything is fine and works as expected; see Q2. The original memory may or may no be used, depending on the details of the assignment. In your example, the original memory would probably be overwritten; in a case like s = std::string("hello");, the buffers of the two strings would probably be swapped.

Ad Q5: String literals are read-only global constants, which the compiler may implement any way it likes. The details are not so important; you will definitely end up with the desired string object in s. See Q3 re temporary objects.

To "learn how to use strings in C++", just go and use them. Treat them like integers. It'll be correct. The beauty of the standard library is that you really don't need to know "how things work"; when you use standard library classes in an idiomatic C++ fashion, all resource management is done automatically and efficiently for you.

like image 28
Kerrek SB Avatar answered Dec 23 '22 23:12

Kerrek SB