Is it legal to mix placement new with a standard delete operation? I'm
curious about the following test case:
#include <memory>
#include <stdexcept>
#include <cassert>
template
<
typename T // requires trivial constructor/destructor
>
class storage
{
private:
// construct:
explicit storage(int size)
: m_Size(size)
{
}
// copy:
storage(const storage&); // noncopyable
// assign:
storage& operator = (const storage&); // nonassignable
public:
// destroy:
~storage()
{
}
// methods:
static std::auto_ptr<storage> create(int size)
{
void *memory =
operator new
(
sizeof(storage)
+ (size - 1) * sizeof(T)
);
std::auto_ptr<storage> result
(
new(memory) storage(size)
);
return result;
}
int size() const
{
return m_Size;
}
// operators:
T& operator [] (int index)
{
if((0 <= index) && (index < m_Size))
{
return m_Data[index];
}
else
{
assert(false && "Invalid index");
throw std::logic_error("Invalid index");
}
}
const T& operator [] (int index) const
{
if((0 <= index) && (index < m_Size))
{
return m_Data[index];
}
else
{
assert(false && "Invalid index");
throw std::logic_error("Invalid index");
}
}
private:
// members:
const int m_Size;
T m_Data[1 /*m_Size*/];
};
int main()
{
std::auto_ptr< storage<int> > s1(storage<int>::create(512));
std::auto_ptr< storage<int> > s2(storage<int>::create(1024));
std::auto_ptr< storage<int> > s3(storage<int>::create(2048));
return 0;
}
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Mike
|
3/24/2011 7:58:13 AM |
|
On 24.03.2011 14:58, Mike Kelley wrote:
>
> Is it legal to mix placement new with a standard delete operation?
This depends... There is no general answer. Since there is no placement
delete you can call manually, the regular delete operator must be used
anyhow in case you use the "placement new" as a "new from a memory
pool", and an overloaded delete operator releases the memory back to the
memory pool. So the question is not really whether it is "legal", but
how you obtained the memory, and whether your memory release - operator
delete - fits to the method the memory has been allocated.
> I'm
> curious about the following test case:
>
> // methods:
> static std::auto_ptr<storage> create(int size)
> {
> void *memory =
> operator new
> (
> sizeof(storage)
> + (size - 1) * sizeof(T)
> );
>
> std::auto_ptr<storage> result
> (
> new(memory) storage(size)
> );
>
> return result;
> }
Note further that, while you're allocating memory sufficient to store
"storage", you never construct the "T" objects which remain thus
uninitialized (anything may happen).
> // operators:
> T& operator [] (int index)
> {
> if((0 <= index) && (index < m_Size))
> {
> return m_Data[index];
See above. m_Data remains unitialized, partially, and what happens with
the out-of bounds access - after all, you lied to the compiler in
defining only one, but not n elements - remains open. A compiler *may*
add bounds checking to your code, after all.
Running into the operator delete with this class then, however, seems
comparably harmless. After all, since the compiler can only pass the
pointer to the object, and not its size, it must have stored the size
elsewhere, when invoking operator new, to have it available when
releasing memory, and you're allocating and releasing the memory from
the same memory pool.
However, the issue with unitialized members remains. I wonder, why not
try valarray, or allocate the memory for the arrays "conservatively"
with operator []? Or what about using a vector, as the simplest
solution? IOW, which problem do you want to solve?
Greetings,
Thomas
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Thomas
|
3/25/2011 3:08:29 AM
|
|
On Mar 24, 2:58 pm, Mike Kelley <mckelle...@gmail.com> wrote:
> Is it legal to mix placement new with a standard delete operation?
I think so (compilers seem to agree), but should not be done. If you
overload new, you better have equivalent overload of delete. Consider:
class test
{
//...
test() { if (problem) throw some_exception; }
void* operator new(size_t, void* p) { return p; }
};
void* p = getmem();
auto_ptr<test> ptest(new (p) test);
If "problem" indeed happens, there is no matching operator delete of
the correct type to possibly free memory. For that, "test" needs
void operator delete(void* p, void*) { ::delete p; }
BTW, without that corresponding "delete", e.g. comeau warns:
Test::operator new(size_t, void *)" has
no corresponding operator delete (to be called if an
exception is
thrown during initialization of an allocated object)
Of course, you are required to match allocation/deallocation in your
new/delete overloads.
Goran.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Goran
|
3/25/2011 10:04:09 AM
|
|
|
2 Replies
295 Views
(page loaded in 0.065 seconds)
Similiar Articles: comp.lang.c++.moderatedmix placement new with a standard delete 2 185 (3/24/2011 7:58:13 AM) Is it legal to mix placement new with a standard delete operation? I'm curious about the following ... How to safely remove an external SCSI device? - comp.sys.sun.admin ...Hi, How do I safely remove an external SCSI device from a ... because gigabit ethernet has now been added to the mix ... the drive from the OS safely but you cannot get a new ... Difference between MATLAB 64-bit and 32-bit - comp.soft-sys.matlab ...While moving to a new platform would be expecetd to ... (And perhaps parallel processing could come into the mix ... Systems | eHow.com Thirty-two-bit systems were the standard ... Does PAUSE have any Side Effect ?? - comp.lang.fortran... matrices & array operations, some of the new ... There is no such thing as a mix of F77 and F90 ... of such variables, I don't see the need to remove them from the standard. Extracting a ROI from an image. - comp.soft-sys.matlabfontSize = 16; % Read in standard MATLAB gray scale demo ... subject we're talking about anymore - please don't mix ... Each ROI plots as a new % figure with three lines of ... Could anyone give me the spice-mode.el - comp.emacsHi, All I am new to *NIX and I am thinking of writing spice code under Emacs. However, I have no idea of Emacs Lisp. Hence, I could not write a packa... Timekeeping broken on Windows XP with multimedia timer enabled (-M ...... time increments in 1 ms steps, > the nominal standard ... 51=A0am, "David J Taylor" <david-tay...@blueyonder.delete ... hacked by adding a Rubidium oscillator to the mix. IBM COBOL Migration to Windows COBOL - comp.lang.cobolNow you can access your DB with standard software as well ... If you remove the flat files it reduces the JCL ... options and allow other things to be added to the mix. ELK M1 Prox Card Reader - comp.home.automation... into keypad programming where you normally enter a new ... My PC to the M1 9 pin serial connector uses a standard ... Use dummy loads for your stereo when you 'remove' the ... Transparency of BMP image pixels - comp.graphics.api.opengl ...Unfortunately no standard program on the planet implements ... free old RGB image sTexture[n].bmp = p; // set new ... How to remove alpha channel from PNG... help please ... The new and delete Operators (C++) - Microsoft Corporation ...However, the new function in the Standard C++ Library (in libcp.lib ... cl /EHsc new_and_delete.cpp libc.lib libcp.lib ... want the non-throwing new, to use the placement-new ... Placement syntax - Wikipedia, the free encyclopedia... operators and functions are known as placement new and placement delete A new ... The Standard C++ syntax for a non-placement new expression is. new new-type-id ( optional ... 7/23/2012 1:45:34 AM
|