Код, использующий конструктор копирования по умолчанию, должен быть segfault, но работает просто отлично

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

Следующий код вызывает конструктор копирования по умолчанию, когда myFunction() называется. Перед выходом из области действия myFunction () мой пользовательский ~myClass() вызывается, который должен вызывать free() на dangerData, Тем не менее, это не похоже на освобождение dangerData!

#include <cstdio>
#include <cstdlib>

class myClass {
static int nextid;
int myID;
char *dangerData;

public:

myClass() {
myID = nextid++;
printf("Constructing myClass number %d\n", myID);
dangerData = (char *)malloc(1024);
dangerData[12] = 0;
}

~myClass() {
printf("Destructing myClass number %d. dangerData = %p\n", myID, (void *) dangerData);
dangerData[12] = 'a'; //Mark the array
free(dangerData); //This call chould free the array... but it doesn't!
}

void msg() {
printf("Message from myClass number %d. dangerData[12] = %d\n", myID, dangerData[12]);
}
};

int myClass::nextid = 1;

void myFunction(myClass param) {
param.msg();
}

int main() {
myClass m;
myFunction(m); //Calls default copy constructor
m.msg();
return 0;
}

Выход из этого кода:

Constructing myClass number 1
Message from myClass number 1. dangerData[12] = 0
Destructing myClass number 1. dangerData = 02f71458. dangerData[12] = 0
Message from myClass number 1. dangerData[12] = 97
Destructing myClass number 1. dangerData = 02f71458. dangerData[12] = 97

Первый вызов к деструктору определенно призвание free() в массиве malloc, однако вызов m.msg() в main() все еще может получить к нему доступ без segfaulting!

Это должно происходить?

0

Решение

Это должно происходить?

Здесь не должно происходить ничего «предполагаемого» или, скорее, «ожидаемого» — вы вызываете неопределенное поведение, так что мог случиться, в том числе и «ничего».

вызов m.msg () в main () все еще может получить к нему доступ без segfaulting!

Это не очень удивительно (но опять же, ни на что не стоит рассчитывать). Освобождение памяти более или менее говорит ОС, что эта память может быть свободно использована / перезаписана. Чем больше внимания уделяется скорости, а не безопасности между вашим компилятором, ОС и их настройками, тем меньше усилий они потратят на то, чтобы пометить эту память как недоступную, и, поскольку вы просто использовали именно эту область памяти, вам пришлось бы выполнять очень строгие проверки ОС. чтобы даже получить segfault там. Также крайне маловероятно, что этот 13-й символ будет перезаписан во время между двумя msg() звонки, так что вы, вероятно, перечитаете то же самое снова.

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector