как узнать, выделен ли объект в куче с помощью new или malloc () текущим модулем?
Вы не можете.Учитывая только значение указателя, не существует переносимого / надежного способа определить, было ли оно выделено new
, malloc()
или даже указывает на что-либо в бесплатном хранилище (как показывает ваш первый метод, указатель переданможет фактически указывать на объект на автоматическом хранении).Это может даже указывать на элемент в массиве.DoSomeThing()
не может сказать, что это невозможно.
Чтобы справиться с этим, пользователи вашей функции должны сами управлять памятью.Первый метод - это то, что обычно делается для чего-то подобного, так как распределение стека происходит автоматически.Например, большая часть Windows API (которая по большей части является C API) сделана так, как ваш первый метод:
WNDCLASSEX wndcls;
// Fill wndcls structure
::RegisterClassEx(&wndcls);
Здесь RegisterClassEx()
не волнует, если мойWNDCLASSEX
находится в стеке, в бесплатном хранилище или как часть массива, пока я передаю указатель, который фактически указывает на WNDCLASSEX
.Таким образом, ваш первый метод действительно является предпочтительным способом работы с ним в реальной практике.
Если поддержка C не требуется, вы также можете использовать ссылки:
void DoSomeThing(SomeObject& out) {}
Преимущество этого подхода заключается в том, что пользователи не могут передавать указатель NULL
, поэтому вам не нужно проверять его.Если DoSomeThing()
не изменяет SomeObject
, то еще лучше использовать ссылки const
:
void DoSomeThing(const SomeObject& out) {}
Приятная вещь в этой сигнатуре состоит в том, что она позволяет работать такому вызову:
DoSomeThing(SomeObject(Arg1,Arg2));
Таким образом, вы получаете "меньше печатать", что вам нужно, не беспокоясь об управлении памятью.