Bob Sacamano
Bob Sacamano

Reputation: 439

Printf and C++ strings

So I have the following code:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
    vector<string> strs;
    strs.push_back("happy");    
    const string& a1 = strs[0];
    strs.push_back("birthday");
    const string& a2 = strs[1];
    strs.push_back("dude");
    const string& a3 = strs[2];

    printf("%s\n", a1.c_str());     
    return 0;
}

which is pretty straightforward but it doesn't work. The printf doesn't print anything. It does print if I change it to:

const string& a1 = strs[0].c_str();

can someone please explain the behavior of it.

Upvotes: 2

Views: 598

Answers (2)

Pranav Kapoor
Pranav Kapoor

Reputation: 1281

strs.push_back("happy");    
const string& a1 = strs[0];

Your reference is valid upto this point. The following push_back however creates problems

strs.push_back("birthday");

This increases the capacity of the vector from 1 to 2. Since the new capacity is greater than the old capacity, all references (as well as iterators) created uptill this point on the vector get invalidated.

As a side note, The c_str gives you a char* (\0 terminated string). If your insertion was of the form

strs.push_back("happ\0y");
const string& a1 = strs[0].c_str();

a1 would have the value 'happ'

Upvotes: 1

Baum mit Augen
Baum mit Augen

Reputation: 50053

Your calls to push_back potentially (and in your case obviously actually) invalidate all references into the vector, namely if the vector is too small to store the new element. You thus cannot use any references into the vector created before a push_back unless you make sure that the vectors capacity is big enough.

If you make sure that the vector has enough capacity for all the elements (i.e. by using std::vector::reserve) before you create the references, your first version will work as expected.

Your second example works because you create a new, temporary string (which has its lifetime extended to the lifetime of the reference) the reference binds to.

Upvotes: 8

Related Questions