Я начинающий в программировании. Читая книгу о С++ в главе посвященной указателям (в частности оператору delete), я наткнулся на то, что в среде VS2017 после выполнения операции delete к любым указателям, которые не ссылаются на одну переменную, возвращается адрес 00008123. В то время как во многих источниках пишется, что значение указателя не изменяется. С чем это может быть связано? Заранее большое спасибо!
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int *p1, *p2;
p1 = new int;
p2 = p1;
cout << p1 << endl;
delete p1;
cout << p1 << endl;
cout << p2 << endl;
system("pause");
return 0;
}
Данная программа выведет случайный код при первом выводе p1 и этот же код при выводе p2. А при втором выводе p1 выведет 00008123.
Данное поведение является документированной функцией студии.
Подробнее можно почитать тут:
https://cloudblogs.microsoft.com/microsoftsecure/2012/04/24/guarding-against-re-use-of-stale-object-references/
и тут:
https://docs.microsoft.com/en-us/cpp/build/reference/sdl-enable-additional-security-checks?view=vs-2017
В настройках проекта опция находится тут (студия 2015, в 17й там же по идее):
Properties -> C/C++ -> General -> SDL Checks.
При включении опции изменяется генерируемый студией асм код.
Исходный с++:
int main()
{
int* p1 { nullptr };
int* p2 { nullptr };
p1 = new int;
p2 = p1;
cout << "pointer 1:" << p1 << endl;
cout << "pointer 2:" << p2 << endl;
delete p1;
cout << "pointer 1:" << p1 << endl;
cout << "pointer 2:" << p2 << endl;
system("pause");
return 0;
}
С выключенной опцией (дебаг):
delete p1;
002F2629 mov eax,dword ptr [p1]
002F262C mov dword ptr [ebp-0ECh],eax
002F2632 push 4
002F2634 mov ecx,dword ptr [ebp-0ECh]
002F263A push ecx
002F263B call operator delete (02F105Ah)
002F2640 add esp,8
(релиз)
delete p1;
00201060 push 4
00201062 push esi
00201063 call operator delete (0201443h)
Вывод:
pointer 1:009C0568
pointer 2:009C0568
pointer 1:009C0568
pointer 2:009C0568
Со включенной опцией (дебаг):
delete p1;
00E92629 mov eax,dword ptr [p1]
00E9262C mov dword ptr [ebp-0ECh],eax
00E92632 push 4
00E92634 mov ecx,dword ptr [ebp-0ECh]
00E9263A push ecx
00E9263B call operator delete (0E9105Ah)
00E92640 add esp,8
00E92643 cmp dword ptr [ebp-0ECh],0
00E9264A jne main+0F8h (0E92658h)
00E9264C mov dword ptr [ebp-0F4h],0
00E92656 jmp main+108h (0E92668h)
00E92658 mov dword ptr [p1],8123h
00E9265F mov edx,dword ptr [p1]
00E92662 mov dword ptr [ebp-0F4h],edx
(релиз)
delete p1;
00D51060 push 4
00D51062 push esi
00D51063 call operator delete (0D51453h)
00D51068 add esp,8
00D5106B mov ecx,8123h
00D51070 test esi,esi
00D51072 mov eax,esi
Вывод:
pointer 1:006D0568
pointer 2:006D0568
pointer 1:00008123
pointer 2:006D0568
В то время как во многих источниках пишется, что значение указателя не изменяется. С чем это может быть связано? Заранее большое спасибо!
Доверяйте документации того компилятора, которым пользуетесь.
И утверждение "адрес указателя не изменяется", и утверждение "после выполнения операции delete к любым указателям, которые не ссылаются на одну переменную, возвращается адрес 00008123" является полнейшей бессмыслицей.
Если речь идет о значении (а не "адресе") указателя, к которому была применен оператор delete
, то это значение не определено. И это не какая-то теоретическая неопределенность, а вполне практическая оптимизационная возможность, которая может приводить к непредсказуемым изменениям значения указателя после delete
.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня на странице несколько ViewНужно чтобы каждый анимировался после предыдущей
При чтении байтов из файла с использовании RandomAccessFile нормально выводится в консоль только латиницаЧтоб выводилась нормально кирилица необходимо...