Search
Write a publication
Pull to refresh

Почему ссылки в С++ могут быть не валидными

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

Синтаксические правила требуют всегда инициализиировать ссылки объектами, на которые они будут ссылаться. И, казалось бы, этого достаточно чтобы гарантировать валидность ссылки. Но объекты в C++ могут иметь разное время жизни и располагаться в разных областях памяти. И если ссылка ссылается (простите за тавтологию) на объект в динамической памяти (выделенный с помощью malloc, new или других аллокаторов) или на объект лежащий в стэке, то компилятор не может проверить валидность объекта во время компиляции.

Пример:

int *p = (int*)malloc( sizeof(int) );
int &r = *p;
free( p );
// r – все еще доступна


Тут все еще существует ссылка, но память, в который хранился объект, освобождена и возможно уже выделена другим потоком, поэтому r ссылается теперь не понятно на что. Аналогинчая ситуация с new/delete.
Можно придумать множество похожих ситуаций. Все ситуации объединяет, то что ссылка изначально была валидной, но объект был уничтожен, а ссылка — нет.

Но бывают ситуации, когда ссылка не является валидной изначально.

#include <stdio.h>

int* genptr() {
return NULL; // код, который потенциально может венуть NULL.
}

int main() {
int& r = *genptr();

printf( "%p\n", &r );
printf( "%i\n", r ); // Segmentation fault

return 0;
}


Этот пример компилируется и запускается на доступных мне компиляторах GCC 4.2 и MSVS 2005. Думается, аналогичная ситуация будет в остальных.

При попытке обратиться к объекту, на который ссылается ссылка, получаем Segmentation fault. Это происходит потому, что компиляторы реализуют ссылки на динамические объекты по средством константных указателей, которые могут содержать NULL, и не проверяют значение в целях оптимизации, оставляя это на совесть программиста.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.