Ошибка в функции и падение в runtime.
От: greydrone Россия  
Дата: 18.05.22 10:29
Оценка:
Написал функцию

std::vector<unsigned char> f( std::vector<unsigned char> &buf, int b )
{
    if ( b == 1 )
    {
        return buf;
    }
    b;
}


Это минимизированный вариант того, что было. Изначально функция должна была возвращать результат, но впоследствии стала работать с аргументом по ссылке.
Нужно было заменить возвращаемый тип данных на void, но этого не было сделано.

Вот вызов

std::vector<unsigned char> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    f( v, 2 );


Приводит к падению (vs2013, vs2015)

Unhandled exception at 0x000FDF58 (msvcp120d.dll) in test2013.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.

на строке

> test2013.exe!std::vector<unsigned char,std::allocator<unsigned char> >::_Tidy() Line 1625 C++


Если заменить
std::vector<unsigned char> f( std::vector<unsigned char> &buf, int b )
на
void f( std::vector<unsigned char> &buf, int b )
(как и нужно было)
проблем нет.


Я не понимаю, почему падает, объясните, пожалуйста.
Re: Ошибка в функции и падение в runtime.
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 18.05.22 10:54
Оценка:
Здравствуйте, greydrone, Вы писали:

G>Я не понимаю, почему падает, объясните, пожалуйста.


Я не настоящий волшебник, но я бы предположил, что так как код возвращает мусор, то дальнейшая попытка обработать этот мусор как vector приводит к обращению по мусорным адресам. Конечно, возвращаемый результат не используется, и компилятор должен был бы такое выкинуть, но либо это дебажная версия, либо в стандарте есть какие-то требования по инициализации структур, либо компилятор не осилил полностью вычистить неиспользуемые вызовы.

Кстати, если функция void, то вместо return buf надо бы просто return. Да и финальная "b" в конце функции непонятно зачем нужна.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re: Ошибка в функции и падение в runtime.
От: watchmaker  
Дата: 18.05.22 13:39
Оценка: +2
Здравствуйте, greydrone, Вы писали:


G> не понимаю, почему падает

С точки зрения языка программа невалидна (при b!=1), так как она содержит неопределённое поведение по правилу [stmt.return 6.6.3.2]

Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.


С точки зрения реализации, падение может происходить, например, после вызова функции при вызове декструктора временного объекта, который никогда не был создан (при b!=1). В зависимости от особенностей реализации проблемы могут быть также чуть раньше или позже и в других местах, но в целом это уже не так важно — неопределённое поведение уже есть.



Но вообще главная проблема в том, что ты компилируешь код без вывода предупреждений и без опции /WX (Treat Warnings as Errors) или эквивалентной. Этот баг компилятор без проблем сам находит. (а ложные предупреждений срабатывания, даже если они будут, легче точечно чинить).
Ну или хотя бы без опции /we4715, чтобы компилятор конкретно этот баг тебе в коде находил.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.