2016-08-22 4 views
0

Следующий пример кода поведение не определено ..Неопределенное поведение станд :: строка при c_str() используется

char * getName() 
{ 
    std::string name("ABCXYZ"); 
    return name.c_str(); 
} 

Это потому, что название выходит из области видимости. Но я хотел понять, как это происходит, когда мы возвращаем std :: string и не порождает неопределенное поведение?

+1

Если вы вернете его ('std :: string') по значению, он будет скопирован/удален, так что это не UB. – tkausl

+0

По всей вероятности, возврат строки 'std :: string' даже не скопировал бы что-либо; возвращаемое значение будет создано, когда это возможно. C++ 17 даже иногда это гарантирует. Если это невозможно сделать, строка, по крайней мере, будет удалена, а не скопирована. На самом деле не о чем беспокоиться. – chris

+1

Это хорошо известная директива C++, в которой вы никогда не должны возвращать локальные объекты по ссылке (или указателю). Вы можете больше узнать об этом в Effective C++, но объяснение Дэвида Шварца охватывает большинство из них. –

ответ

1

Просто потому, что возвращение инструкция копирует или перемещает (см. C++ 11) возвращенный объект.

С помощью этого кода:

std::string getName() { 
    std::string name("ABCXYZ"); 
    return name; 
} 

строка имя будут скопированы и возвращены к абоненту.

С вашим кодом, возвращение сделает копию указателя (потому что ваша функция возвращает указатель), а не заостренным объекта. Это создаст UB.

+0

Может быть скопирован. У современных компиляторов есть большой пул трюков, которые они используют, чтобы избежать копирования данных. Pop «Оптимизация возвращаемого значения» и «Копировать Elision» в веб-поиск по вашему выбору, если вам интересно узнать больше о двух наиболее распространенных трюках. – user4581301

+0

@ user4581301 Я очень хорошо знаю эти «трюки». Я не упоминал их, потому что OT. Во всяком случае, то, что я говорил, это просто относится к стандарту, давайте рассмотрим аспекты, зависящие от платформы ;-) –

5

Когда вы присвоите return значение, это значение будет безопасно возвращено вызывающему абоненту. Вот что делает оператор return.

В случае, если вы звоните c_str, значение, которое вы возвращаете, является указателем на строку. Как только строка будет уничтожена, этот указатель теперь указывает на ничего в частности. Значение равно благополучно возвращено, это просто, что вы ничего не можете с ним сделать безопасно.

Значение string - это содержимое строки. Таким образом, в этом случае содержимое строки передается вызывающему. Можно сказать, что основной целью класса std::string является предоставление объекта, значение которого является содержимым строки.

Смежные вопросы