#c
#c
Вопрос:
Я новичок в C , и мне было интересно, почему…
#include <iostream>
using namespace std;
class myClass{
public:
void myMethod(){
cout << "It works!" << endl;
}
myClass(){
cout << "myClass is constructed!" << endl;
}
~myClass(){
cout << "This class is destructed!" << endl;
}
};
int main()
{
myClass c;
c.myMethod();
myClass *e = amp;c;
delete e;
cout << "This is from main" << endl;
return 0;
}
Итак, есть код. и вывод
myClass is constructed!
It works!
This class is destructed!
Мне интересно, куда делся вывод «This is from main» .. не выполняет ли C коды после ключевого слова delete?
Комментарии:
1. Неопределенное поведение не определено.
2. Я думаю, вы получаете ошибку сегментации или другую ошибку времени выполнения вместо ожидаемого результата
3. удаление объекта, который вы не создали, приводит к неопределенному поведению.
4. Удалите строки
myClass *e = amp;c;
,delete e;
и программа будет вести себя правильно. c был выделен в стеке. Вы не можете удалить из стека!
Ответ №1:
Вы можете использовать только delete
те объекты, которые были созданы с new
помощью .
То, что вы делаете, — это UB, с помощью двойного удаления.
Кстати, хотя в этом случае ваша программа остановила выполнение сразу после оператора, в котором был UB, это не обязательно должно происходить таким образом, потому что
Однако, если любое такое выполнение содержит неопределенную операцию, этот Международный стандарт не предъявляет никаких требований к реализации, выполняющей эту программу с этим вводом (даже в отношении операций, предшествующих первой неопределенной операции).
Комментарии:
1. Итак, что я сделал, я удалил ссылку на класс?
2. Вы
delete
создали экземпляр, который не был выделенnew
. Это не разрешено.3. О, так это вызвало ошибку и просто завершило мою программу. Спасибо.
Ответ №2:
У вас неопределенное поведение. Вам не разрешено delete
использовать то, что не было выделено new
. При этом у вас неопределенное поведение, и вашей программе разрешено делать то, что она хочет.
Скорее всего, вы должны были получить какую-то серьезную ошибку, которая остановила запуск программы.
Комментарии:
1. Однако я не получил никакой ошибки. Я использовал cpp.sh потому что меня не было дома XD
2. Как я уже сказал, вам не обязательно. Это UB, поэтому ничего не происходит, это совершенно правильно.
3. Строго говоря, неопределенное поведение не означает, что программе разрешено делать то, что она хочет. Вместо этого это означает, что то, что будет делать программа, вообще не указано.
Ответ №3:
Вы вызвали неопределенное поведение, удалив то, что не было обновлено. Вам не нужно удалять материал, который просто указывает на какое-то общее местоположение. Вы удаляете только то, что создали, вызвав new
(не размещая новое!).
Ответ №4:
Возможно, вам стоит прочитать о стековой и кучной памяти.
Вы должны освободить только тогда, когда вы используете malloc (или другие варианты, такие как calloc).
Например:
char *c = (char *)malloc(255);
...
free(c)
Удалять необходимо только в том случае, если вы используете new.
MyClass *e = new MyClass()
...
delete e
Вы должны удалить [], только если вы используете new[]
char *data = new char[20]
...
delete[] data
Теперь, если вы сделаете что-то вроде этого:
...
{
int x;
x = 3;
}
x будет уничтожен после фиксации, потому что он выходит за рамки. Это помещает x в стек. Однако, если вы используете malloc, new или delete, сама переменная может быть потеряна, если вы не будете осторожны, но память будет выделена. Это утечка памяти.
То, что у вас есть, еще более опасно. Вы удаляете что-то, что не было выделено. Поведение не определено. Со временем и терпением опытный хакер может изучить поведение и, возможно, сможет проникнуть в вашу систему и получить те же права, что и ваша программа.