Какова длительность импликации «указатель не связан ни с одним другим указателем»? - PullRequest
2 голосов
/ 23 сентября 2011

В настоящее время Visual C ++ поставляется со средой выполнения, где malloc() украшено __declspec( restrict ).

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

void* memory1 = malloc( 10 );
free( memory1 );
void* memory2 = malloc( 10 );
//here memory1 may be equal to memory2

В этом случае два указателя могут указывать на одно и то же местоположение. Как это соотносится с , не может быть наложен ни на какой другой указатель значение __declspec( restrict )?

Ответы [ 2 ]

4 голосов
/ 23 сентября 2011

Поскольку после освобождения (memory1) доступ к чему-либо через указатель memory1 является неопределенным поведением (носовые демоны и т. Д.), И, следовательно, компилятор может оптимизировать, предполагая, что memory2 не является псевдонимом любого другого указателя после malloc () позвоните.

Что касается того, почему это важно, предполагая, что сам компилятор не имеет внутренней информации о семантике malloc (), т.е. что он обрабатывает ее так же, как любую другую функцию, то он не может предположить, что возвращенный указатель не является псевдонимом других указатель. __declspec(restrict) (или, что то же самое, __attribute__((malloc)) в GCC) сообщает компилятору, что указатель не является псевдонимом какого-либо другого указателя, что допускает некоторые оптимизации, невозможные в противном случае.

3 голосов
/ 23 сентября 2011

Стандарт говорит об «времени жизни объекта» (§3.8 в N3290):

Время жизни объекта типа T заканчивается, когда:
- если T является типом класса с нетривиальным деструктором (12.4), начинается вызов деструктора, или
- хранилище, которое занимает объект, используется повторно или освобождается.

После того, как вы free сделали блок, на который указывает memory1, этот объект мертв. Он перестал существовать. Разыменование этого указателя будет неопределенным поведением.

memory2 можно присвоить тот же адрес памяти, но он ничего не будет "псевдоним": то, что было в этом месте, прошло.

...