{"id":280,"date":"2010-10-24T08:23:00","date_gmt":"2010-10-24T10:23:00","guid":{"rendered":"http:\/\/www.ragestorm.net\/blogs\/?p=280"},"modified":"2010-10-24T08:23:00","modified_gmt":"2010-10-24T10:23:00","slug":"deleting-a-new","status":"publish","type":"post","link":"https:\/\/www.ragestorm.net\/blogs\/?p=280","title":{"rendered":"Deleting a New"},"content":{"rendered":"<p>Recently I&#8217;ve been working on some software to find memory leaks and fix its fragmentation too. I wanted to start with some example of a leak. And next time I will talk about the fragmentations also.<\/p>\n<p>The leak happens when you allocate objects with new [] and delete (scalar) it. If you&#8217;re a c++ savvy, you might say &#8220;WTF, of course it leaks&#8221;. But I want to be honest for a moment and say that except from not calling the destructors of the instances in the array, I really did not except it to leak. After all, it&#8217;s a simple memory pointer we are talking about. But I was wrong and thought it&#8217;s worth a post to share this with you.<\/p>\n<p>Suppose we got the following code:<\/p>\n<pre lang=\"c++\">\r\nclass A {\r\n public:\r\n  A() { }\r\n  ~A() { }\r\n private:\r\n  int x, y;\r\n};\r\n\r\n...\r\nA * a = new A[3];\r\n...\r\ndelete a; \/\/ BUGBUG <\/pre>\n<p>What really happens in the code, how does the constructors and destructors get called? How does the compiler know whether to destroy a single objects, or how many objects to destroy when you&#8217;re finished working with the array ?<\/p>\n<p>Well, first of all, I have to warn you that some of it is implementation specific (per compiler). I&#8217;m going to focus on Visual Studio though.<\/p>\n<p>The first thing to understand is that the compiler knows which object to construct and destroy. All this information is available in compilation time (in our case since it&#8217;s all static). But if the object was dynamic, the compiler would have called the destructor dynamically, but I don&#8217;t care about that case now&#8230;<\/p>\n<p>So allocating memory for the objects, it will eventually do malloc(3 * sizeof(A)) and return a pointer to assign in the variable &#8216;a&#8217;. Here&#8217;s the catch, the compiler can&#8217;t know how many destructors to call when it wants to delete the array, right? It has to bookkeep the count somehow. But Where??<br \/>\nTherefore the call to the memory allocation has more to it. The way MSVC does it is as following (some pseudo code):<\/p>\n<pre lang=\"c++\">\r\nint* tmpA = (int*)malloc(sizeof(A) * 3 + sizeof(int)); \/\/ Notice the extra space for the integer!\r\n*tmpA = 3; \/\/ This is where it stores the count of instances! ta da\r\nA* a = (A*)(tmpA + 1); \/\/ Skip that integer, really assigns the pointer allocated + 4 bytes in 'a'.<\/pre>\n<p>Now all it has to do is calling the constructors on the array for each entry, easy.<br \/>\nWhen you work with &#8216;a&#8217; the implementation is hidden to you, eventually you get a pointer you should only use for accessing the array and nothing else.<br \/>\nAt the end you&#8217;re supposed to delete the array. The right way to delete this array is to do &#8216;delete []a;&#8217;. The compiler then understands you ask to delete a number of instances rather than a single instance. So it will loop on all the entries and call a destructor for each instance, and at last free the whole memory block. One of the questions I asked in the beginning is how would the compiler know how many objects to destroy? We already know the answer by now. Simple, it stored the count <i>before<\/i> the pointer you hold.<\/p>\n<p>So deleting the array in a correct manner (and reading the counter) would be as easy as:<\/p>\n<pre lang=\"c++\">\r\nint* tmpA = (int*)a - 1; \/\/ Notice we take the pointer the compiler handed to you, and get the 'count' from it.\r\nfor (int i = 0; i < *tmpA; i++) a[i].~a();\r\nfree (tmpA); \/\/ Notice we call free() with the original pointer that got allocated! <\/pre>\n<p>So far so good, right? But the leak happens if you call a scalar delete on the pointer you get from allocating a new array. And that's the problem even if you have an array of primitive types (like integers, chars, etc) that don't require to call a destructor you still leak memory. Why's that?<br \/>\nSince the new array, as we saw in this implementation returns you a pointer, which <b>does not<\/b> point to the beginning of the allocated block. And then eventually you call delete upon it, will make the memory manager not find the <i>start<\/i> of the allocated block (cause you feed it with an offset into the allocated block) and then it has a few options. Either ignore your call, and leak that block. Crash your application or give you a notification, aka Debug mode. Or maybe in extreme cases cause a security breach...<\/p>\n<p>In some forum I read that there are many unexpected behaviors in our case, one of them made me laugh so hard, I feel I need to share it with you:<br \/>\n\"A* a = new A[3]; delete a; Might get the first object destroyed and released, but keep the rest in memory\".<\/p>\n<p>Well it doesn't take a genius to understand that the compiler prefers to bulk allocate all objects in the same block...and yet, funny.<br \/>\nThe point the guy tries to make is that you cannot know what the compiler implementation is, as weird as it might be, don't ever rely on it. And I totally agree.<\/p>\n<p>So in our case a leak happens in the following code:<br \/>\n<b>(wrong:)<\/b><\/p>\n<pre lang=\"c++\">\r\nint*a = new int[100];\r\n...\r\ndelete a;<\/pre>\n<p>The point is that when you new[], you <del>should<\/del> must call a corresponding delete [].<br \/>\nExcept from the need to make your code readable and correct, it won't be broken, and never trust the compiler, just code <i>right<\/i> in the first place.<\/p>\n<p>And now you can imagine what happens if you alloc a single object and tries to delete[] it. Not healthy, to say the least.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently I&#8217;ve been working on some software to find memory leaks and fix its fragmentation too. I wanted to start with some example of a leak. And next time I will talk about the fragmentations also. The leak happens when you allocate objects with new [] and delete (scalar) it. If you&#8217;re a c++ savvy, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":""},"categories":[20,13],"tags":[48,49],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbWKd-4w","_links":{"self":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/280"}],"collection":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=280"}],"version-history":[{"count":1,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/280\/revisions"}],"predecessor-version":[{"id":281,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/280\/revisions\/281"}],"wp:attachment":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}