<p>Say I have the following C++:</p>

<pre><code>char *p = new char[cb];
SOME_STRUCT *pSS = (SOME_STRUCT *) p;
delete pSS;
</code></pre>

<p>Is this safe according to the C++ standard? Do I need to cast back to a <code>char*</code> and then use <code>delete[]</code>? I know it'll work in most C++ compilers, because it's plain-ordinary-data, with no destructors. Is it guaranteed to be safe?</p>

[{'answer_id': 70904, 'author': 'Daniel James', 'author_id': 2434, 'author_profile': 'https://Stackoverflow.com/users/2434', 'pm_score': 3, 'selected': False, 'text': '<p>No, it\'s undefined behaviour - a compiler could plausibly do something different, and as the C++ FAQ entry that <a href="https://stackoverflow.com/questions/70880/deleting-a-buffer-through-a-different-type-of-pointer#70905">thudbang</a>  linked to says, <code>operator delete[]</code> might be overloaded to do something different to <code>operator delete</code>. You can sometimes get away with it, but it\'s also good practice to get into the habit of matching delete[] with new[] for the cases where you can\'t.</p>\n'}, {'answer_id': 70905, 'author': 'thudbang', 'author_id': 11661, 'author_profile': 'https://Stackoverflow.com/users/11661', 'pm_score': 4, 'selected': True, 'text': '<p>It\'s not guaranteed to be safe.  Here\'s a relevant link in the C++ FAQ lite:</p>\n\n<p>[16.13] Can I drop the <code>[]</code> when deleting array of some built-in type (<code>char</code>, <code>int</code>, etc.)?</p>\n\n<p><a href="https://isocpp.org/wiki/faq/freestore-mgmt#delete-array-built-ins" rel="nofollow noreferrer">http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.13</a></p>\n'}, {'answer_id': 70910, 'author': 'warren', 'author_id': 4418, 'author_profile': 'https://Stackoverflow.com/users/4418', 'pm_score': 0, 'selected': False, 'text': "<p>While this <em>should</em> work, I don't think you can guarantee it to be safe because the SOME_STRUCT is not a char* (unless it's merely a typedef).</p>\n\n<p>Additionally, since you're using different types of references, if you continue to use the *p access, and the memory has been deleted, you will get a runtime error.</p>\n"}, {'answer_id': 70941, 'author': 'Igor Semenov', 'author_id': 11401, 'author_profile': 'https://Stackoverflow.com/users/11401', 'pm_score': 2, 'selected': False, 'text': '<p>C++ Standard [5.3.5.2] declares:</p>\n\n<blockquote>\n  <p>If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion\n  function, and the converted operand is used in place of the original operand for the remainder of this section. In either\n  alternative, the value of the operand of delete may be a null pointer value. <strong>If it is not a null pointer value, in the first\n  alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a\n  subobject (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined. In the second\n  alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous\n  array new-expression.77) If not, the behavior is undefined. [ Note: this means that the syntax of the delete-expression\n  must match the type of the object allocated by new, not the syntax of the new-expression. —end note ]</strong> [ Note: a pointer\n  to a const type can be the operand of a delete-expression; it is not necessary to cast away the constness (5.2.11) of the\n  pointer expression before it is used as the operand of the delete-expression. —end note ]</p>\n</blockquote>\n'}, {'answer_id': 70942, 'author': 'Zooba', 'author_id': 891, 'author_profile': 'https://Stackoverflow.com/users/891', 'pm_score': 2, 'selected': False, 'text': '<p>I highly doubt it.</p>\n\n<p>There are a lot of questionable ways of freeing memory, for example you can use <code>delete</code> on your <code>char</code> array (rather than <code>delete[]</code>) and it will likely work fine. I <a href="http://www.byteclub.net/blog/zooba/?p=77" rel="nofollow noreferrer">blogged</a> in detail about this (apologies for the self-link, but it\'s easier than rewriting it all).</p>\n\n<p>The compiler is not so much the issue as the platform. Most libraries will use the allocation methods of the underlying operating system, which means the same code could behave differently on Mac vs. Windows vs. Linux. I have seen examples of this and every single one was questionable code.</p>\n\n<p>The safest approach is to always allocate and free memory using the same data type. If you are allocating <code>char</code>s and returning them to other code, you may be better off providing specific allocate/deallocate methods:</p>\n\n<pre><code>SOME_STRUCT* Allocate()\n{\n    size_t cb; // Initialised to something\n    return (SOME_STRUCT*)(new char[cb]);\n}\n</code></pre>\n\n<p>&nbsp;</p>\n\n<pre><code>void Free(SOME_STRUCT* obj)\n{\n    delete[] (char*)obj;\n}\n</code></pre>\n\n<p>(Overloading the <code>new</code> and <code>delete</code> operators may also be an option, but I have never liked doing this.)</p>\n'}, {'answer_id': 71090, 'author': '0124816', 'author_id': 11521, 'author_profile': 'https://Stackoverflow.com/users/11521', 'pm_score': 0, 'selected': False, 'text': "<p>This will work OK if the memory being pointed to <strong>and</strong> the pointer you are pointing with are both POD. In this case, no destructor would be called anyhow, and the memory allocator does not know or care about the type stored within the memory.</p>\n\n<p>The only case this is OK with non-POD types, is if the pointee is a subtype of the pointer, (e.g. You are pointing at a Car with a Vehicle*) and the pointer's destructor has been declared virtual.</p>\n"}, {'answer_id': 71442, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<p>This isn't safe, and non of the responses so far have emphasized enough the madness of doing this. Simply don't do it, if you consider yourself a real programmer, or ever want to work as a professional programmer in a team. You can only say that your struct contains non destructor <em>at the moment</em>, however you are laying a nasty possibly compiler and system specific trap for the future. Also, your code is unlikely to work as expected. The very best you can hope for is it doesn't crash. However I suspect you will slowly get a memory leak, as array allocations via new very often allocate extra memory in the bytes <em>prior</em> to the returned pointer. You won't be freeing the memory you think you are. A good memory allocation routine should pick up this mismatch, as would tools like Lint etc. </p>\n\n<p>Simply don't do that, and purge from your mind whatever thinking process led you to even consider such nonsense.</p>\n"}, {'answer_id': 72444, 'author': 'Roger Lipscombe', 'author_id': 8446, 'author_profile': 'https://Stackoverflow.com/users/8446', 'pm_score': 0, 'selected': False, 'text': "<p>I've changed the code to use malloc/free. While I know how MSVC implements new/delete for plain-old-data (and SOME_STRUCT in this case was a Win32 structure, so simple C), I just wanted to know if it was a portable technique.</p>\n\n<p>It's not, so I'll use something that is.</p>\n"}, {'answer_id': 78368, 'author': 'paercebal', 'author_id': 14089, 'author_profile': 'https://Stackoverflow.com/users/14089', 'pm_score': 0, 'selected': False, 'text': "<p>If you use malloc/free instead of new/delete, malloc and free won't care about the type.</p>\n\n<p>So if you're using a C-like POD (plain old data, like a build-in type, or a struct), you can malloc some type, and free another. <strong>note that this is poor style even if it works</strong>.</p>\n"}, {'answer_id': 108579, 'author': 'CB Bailey', 'author_id': 19563, 'author_profile': 'https://Stackoverflow.com/users/19563', 'pm_score': 2, 'selected': False, 'text': '<p>This is a very similar question to the one that I answered here: <a href="https://stackoverflow.com/questions/73134/will-this-c-code-cause-a-memory-leak-casting-vector-new#108454">link text</a></p>\n\n<p>In short, no, it\'s not safe according to the C++ standard. If, for some reason, you need a SOME_STRUCT object allocated in an area of memory that has a size difference from <code>size_of(SOME_STRUCT)</code> (and it had better be bigger!), then you are better off using a raw allocation function like global <code>operator new</code> to perform the allocation and then creating the object instance in raw memory with a placement <code>new</code>. Placement <code>new</code> will be extremely cheap if the object type has no constructor.</p>\n\n<pre><code>void* p = ::operator new( cb );\nSOME_STRUCT* pSS = new (p) SOME_STRUCT;\n\n// ...\n\ndelete pSS;\n</code></pre>\n\n<p>This will work most of the time. It should always work if <code>SOME_STRUCT</code> is a POD-struct. It will also work in other cases if <code>SOME_STRUCT</code>\'s constructor does not throw and if <code>SOME_STRUCT</code> does not have a custom operator delete. This technique also removes the need for any casts.</p>\n\n<p><code>::operator new</code> and <code>::operator delete</code> are C++\'s closest equivalent to <code>malloc</code> and <code>free</code> and as these (in the absence of class overrides) are called as appropriate by <code>new</code> and <code>delete</code> expressions they can (with care!) be used in combination.</p>\n'}]
['https://Stackoverflow.com/questions/70880', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/8446/']