2015-05-05 3 views
-2

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

std::string conversation; 

const char *GetFoo() 
{ 
    static std::string word; 

    word ="hello "; 
    word +="buddy."; 
    word +=" How are things?"; 
    return word.c_str(); 
} 

void CallGetFoo() 
{ 
    const char *pp = GetFoo(); 
    conversation +=pp; 

    cout<<pp; 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CallGetFoo(); 
    return 0; 
} 
+0

Почему бы не возвратить 'std :: string' –

+0

Удаление' static' является ошибкой. Вы получаете неопределенное поведение. – juanchopanza

+0

ok благодаря Ed Heal и Juanchopanza. Вместо этого я попытаюсь вернуть std :: string. Но есть и другое. Этот проект работает уже несколько лет. Он действует только на новой платформе. –

ответ

3

Вы столкнулись с классической проблемой возврата указателя/ссылки на данные, которые являются локальными для функции. Когда вы удаляете статическое ключевое слово, тогда переменная слова разрушается в конце функции. Это означает, что c_str, который он возвращает, будет мусором, и вы получите неопределенное поведение. Статическое ключевое слово удерживает объект вокруг так, чтобы он оставался одним и тем же путем нескольких вызовов функции. Как и комментарии, вам лучше вернуть строку std ::.

Возврат std :: string скопирует содержимое локальной переменной в std :: string вызывающего. Скорее всего, компилятор сможет оптимизировать копию и сделать что-то под названием Оптимизация возвращаемых значений (RVO), но это отдельная тема.

+0

Мы возвращаем std :: String вместо этого, потому что ... закончите мысль, чтобы OP понимал, почему это лучше, чем возврат локального var. –

+0

Спасибо, Скотт и Майкл .. Я попытаюсь вернуть std :: string. Но по второму вопросу этот код работает уже много лет, но он падает на новом устройстве этого заявления, так что вы знаете, что может вызвать потенциальные проблемы? –

+0

Когда вы входите в мир неопределенного поведения, очень сложно точно определить, почему все работает так, как они есть. Возможно, что конкретный компилятор или платформа, которые вы использовали раньше, ничего не делали с массивом символов, который был выделен для строки после ее разрушения, а новый - для нее. Это все предположения платформы/компилятора, когда вы попадаете в эти ситуации. – Scott