2017-01-08 7 views
7

Представьте себе такой код:Valgrind не показывает недопустимый доступ к памяти с неправильно используются c_str()

string f() 
{ 
    string r = "ab"; 
    return r; 
} 

int main() { 
    const char *c = f().c_str(); 
    printf("%s.\n", c); 
    return 0; 
} 

Этот код может врезаться, верно? Потому что эта строка, которую c указывает на уничтожен. Но запуск его через Valgrind не показывает никаких недопустимых обращений к памяти. Зачем? Я знаю, что Valgrind не может проверить стек, но «ab» на самом деле находится на куче, верно?

+8

Небольшая оптимизация строки. Попробуйте '«aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc»' – StoryTeller

+8

Что вы имеете в виду «Теперь мой актуальный вопрос заключается в следующем»? Спросите ** новый вопрос ** пожалуйста. –

ответ

10

Этот код может произойти сбой, не так ли? Потому что эта строка, которую c указывает на уничтожен.

Право. У этого есть неопределенное поведение, и это означает, что любое поведение разрешено. Сбой - одна из вещей, которые могут произойти. Продолжение, как будто ничего плохого, как это происходит при вашей реализации, является еще одним.

Я знаю, что Valgrind не может проверить стек, но «ab» на самом деле находится на куче, верно?

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

Если вы говорите, что Valgrind не может проверять доступ к стекам, а ваш возвращенный std::string хранится в стеке, это объясняет, почему Valgrind не видит никаких проблем.