2015-07-30 6 views
0

Я наткнулся на этот код в онлайн-тесте. Безопасен ли этот код? Какова продолжительность жизни литералов, которые я использую для создания экземпляров? Ли буквальный «Джон» уничтожается после создания экземпляра p1 (поскольку это завершает выражение, в котором используется литерал).Инициализация элемента char * со строковым литералом

class Person { 
    public: 

    char *name; 
    Person(char *s) { name = s} 
    inline void setName(char *newName) {name = newName;} 

}; 

int main(){ 

    Person p1("John"); 

    Person p2("Steve"); 

    p1.setName("Rick"); 
    p2 = p1; 
    return 0; 

} 

ответ

2

char * не удаляется нигде (или free'd), поэтому он безопасен. Исключение будет выбрано, если вы попытаетесь освободить его, поскольку литералы хранятся в другой части памяти в динамической памяти. Литералы живут на протяжении всей жизни процесса.

+0

Определите «безопасный». Если вы задокументируете, что класс может быть построен только из строкового литерала, тогда это будет хорошо, но в противном случае у него будут серьезные проблемы с правами собственности/жизни. Это очень плохой дизайн. Что касается «секции .bss исполняемого файла», то это вопрос реализации, не определенный C++, и реализация не была задана в вопросе. –

+0

_ «Исключение будет выбрано, если вы попытаетесь освободить его». Это также детализация реализации, вероятно, вплоть до чистой вероятности. Код для стандартов, и у вас будет намного лучшее время. Это буквально, почему они там. –

1

Код является незаконным, поскольку строковый литерал не может инициализировать char*. Итак, нет.

Это становится законным, если вы делаете тип const char*. Но тогда это все еще небезопасно.

Если вы можете гарантировать, что в него будет передан только строковый литерал, то это прекрасно, потому что строковый литерал гарантированно будет жить на протяжении всей программы. Ваш класс не приведет к уничтожению литерала.

Но вы не можете этого гарантировать. Вы можете только документировать это как предварительное условие, и это действительно слабо.

Это действительно плохой дизайн.

+0

inb4 ныть, нет, сейчас 2015 год –

+0

На самом деле, это было законно в C++ 03, но устарело. –

+0

@ ex-bart: * facepalm * –

1

Безопасен ли этот код?

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

Какова продолжительность жизни литералов, которые я использую для создания экземпляров?

Они хранятся статически в любой реализации, поэтому в основном до конца main.

ли буквальный «Джон» разрушается после p1 инстанциируется

Неа это все еще там, но ничего не относится к нему больше (нет указателей или ссылки), поэтому вы не можете получить обратно на него без каких-либо махинаций.

+0

«Это плохой дизайн по нескольким причинам», - можете ли вы углубиться в это более подробно. –

+0

@Matt: Я уже и вы их отвергли. Позор. –

+0

@LightnessRacesinOrbit не понял, что вы написали этот ответ –

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