|
This thread is locked; no one can reply to it. |
1
2
|
How to delete allocated memory at void pointer? |
NonLegato
Member #6,716
December 2005
|
I'm writing my linked lists class. Its nodes point to actual element that was allocated outside the class. And i'd like to be able to deallocate both nodes and elements from inside the class. What i have to do with it? I got Dev-C warning when delete void* directly! by deleting node->data. So I'm not sure I can do that. But casting to (BYTE*) and do delete[] stop compiler to complain anymore. Does delete operator know the size of allocated memery point by void*? Below is a small part of my code.
|
miran
Member #2,407
June 2002
|
Quote: Does delete operator know the size of allocated memery point by void*? I think yes. But if you're writing this for anything other than academic purposes, I suggest you switch to STL. -- |
OICW
Member #4,069
November 2003
|
Why to switch to STL? I know there are namespaces just for this, but if you write class on your own, you know how it works and you can easily modify it to whatever you want. For example I included linked list to object classes in my project. I cannot imagine what junk I'd have in my code when using STL. But anyway I'm not saying it's wrong. Whether to use it or not depends on circumstances. But one note - STL makes your programs a bit overweight. [My website][CppReference][Pixelate][Allegators worldwide][Who's online] |
miran
Member #2,407
June 2002
|
Then why do you use Allegro? Why don't you write your own code for loading bitmaps, blitting them, playing samples, setting gfx mode, getting mouse and keyboard input, etc? If you did, you would know exactly how it worked. Let me tell you why. Because someone already wrote that for you and it works. It has been tried and tested many times and there's no reason to reinvent the wheel. -- |
NonLegato
Member #6,716
December 2005
|
Quote: But if you're writing this for anything other than academic purposes, I suggest you switch to STL. I'm using Dev-C++. I still remember that using STL with MinGW results in a very large exe-file. So I avoid it if I don't use much of it. I've ever used VC++ before and it doesn't have this STL issue. |
OICW
Member #4,069
November 2003
|
Ok Miran you're right, but I'm talking about basic data structure. First it's good to know how it works, second it's better to write your own which will be suit you, third STL produces very large exe files. But again I'm not saying STL s wrong. But when you need simple linked list, then I don't see any need to include STL. [My website][CppReference][Pixelate][Allegators worldwide][Who's online] |
amarillion
Member #940
January 2001
|
Quote: I'm using Dev-C++. I still remember that using STL with MinGW results in a very large exe-file. So I avoid it if I don't use much of it. Proof? In my experience STL code is always highly efficient, except perhaps when you talk about speed of compilation. Maybe the exe gets so large because you use many different vector types, and forgot to strip symbols? -- |
NonLegato
Member #6,716
December 2005
|
Quote: Proof? In my experience STL code is always highly efficient, except perhaps when you talk about speed of compilation. Maybe the exe gets so large because you use many different vector types, and forgot to strip symbols? I have done some experiments on basic hello world code. It is an iostream part of STL that causes big exe files. hello world 19 KB + my owned linked list 54 KB + std::iostream 572 KB + std::list 56 KB + std::vector 61 KB Well, I still need your advice on deleting void pointer. Dev C++ warning make me unsure that deleting void* will free allocated memory properly. |
Wil Renczes
Member #5,921
June 2005
|
Going back to the original question: Firstly, I don't think you can call delete on a void *. Delete needs to know the size of the allocated structure - in fact (at least with MS, anyway), if you step with the debugger inside of new/delete, you'll see that internally it uses malloc/free. I think your code though is highly perilous ground - the point of C++ is to avoid pointer casting & void types and the inherent danger of the lack of type safety found in procedural C. I think what you're probably looking for is this: try making your linked list class a template class. In fact, this is exactly what STL does for its container classes. |
HoHo
Member #4,534
April 2004
|
Quote: I have done some experiments on basic hello world code. It is an iostream part of STL that causes big exe files. Could you share the code, please? I did a simple hello world test myself and with simple std::iostream and std::list file size was ~25k, 5k when stripped, 4.5k when UPX'ed. Perhaps my test was too simple though. Also, this was done under Linux with GCC 3.4.4. In theory I think there shouldn't be major difference between OS'es because the compiler is the same. Though I noticed that with custom list you saved a whole two kB's As for deleting void*, I don't know. I haven't used them in my C++ projects because I haven't seen the need __________ |
NonLegato
Member #6,716
December 2005
|
Quote: Could you share the code, please? I did a simple hello world test myself and with simple std::iostream and std::list file size was ~25k, 5k when stripped, 4.5k when UPX'ed. Perhaps my test was too simple though. With iostream included, my hello world grows to 465KB when compiled without debugging info. (Dev C++ v4.9.9.2 and MinGW32 v3.4.2) #include <cstdlib> #include <iostream> using namespace std; int main(int argc, char *argv[]) { printf("Hello World\n"); return 0; }
Quote:
I noticed that with custom list you saved a whole two kB's I just try to write my own class for fun. And if it turns to be simpler and smaller than STL I will use it in my game instead. Maybe iostream link size scared me out. |
Hrvoje Ban
Member #4,537
April 2004
|
Bare main() -> 6KB std::list with all function called -> 27 KB Difference -> 21 KB Delete should knows size (since in most cases it uses delete which takes void * anyway) but since type is unknown it doesn't know which destructor to call. Remember, object's destructor must be called when object is destroyed. |
BAF
Member #2,981
December 2002
|
Why do you want a void*? Just use a char*, it works the same, as each char is 1 byte, and you can allocate + free it with no problems. |
HoHo
Member #4,534
April 2004
|
With that code you gave I got this: #g++ linklist.cpp ; ls -l a.out -rwxr-xr-x 1 hoho users 8187 Dec 27 14:16 a.out #cp a.out a1.out #upx -9 a1.out #ls -l a1.out -rwxr-xr-x 1 hoho users 4830 Dec 27 14:17 a1.out #cp a.out a2.out #strip a2.out #ls -l a2.out -rwxr-xr-x 1 hoho users 4420 Dec 27 14:17 a2.out Perhaps mingw really does create bigger executeables under windows. With a STL list test I got this result:
#g++ linklist.cpp; ls -l a.out -rwxr-xr-x 1 hoho users 19057 Dec 27 14:24 a.out #cp a.out a1.out ; upx -9 a1.out ; ls -l a1.out -rwxr-xr-x 1 hoho users 8575 Dec 27 14:25 a1.out #cp a.out a2.out ; strip a2.out ; ls -l a2.out -rwxr-xr-x 1 hoho users 11060 Dec 27 14:25 a2.out #upx -9 a2.out ls -l a2.out -rwxr-xr-x 1 hoho users 6084 Dec 27 14:25 a2.out Not too bad. I guess the size difference might come from if programs under Linux are dynamically linked to libstdc++. You might want to try what UPX and strip can do for the executeables under Windows. I wouldn't be surprised if the 465kB gets reduced to <50kiB Quote: I just try to write my own class for fun. There is nothing bad about writing your own classes but you might want to write them similar to STL by using templates so you wouldn't have such problems with void pointers. __________ |
Kitty Cat
Member #2,815
October 2002
|
Why are you trying to delete a void*? You can't new a void*. -- |
Steve++
Member #1,816
January 2002
|
Quote: Why are you trying to delete a void*? You can't new a void*. This indicates a design error. You should be deleting the object in the same context as you're creating it. Otherwise memory leaks will be the least of your problems. |
Billybob
Member #3,136
January 2003
|
Quote: Firstly, I don't think you can call delete on a void *. Delete needs to know the size of the allocated structure
No, it does not need to know the size. The OS does, or the underlying allocation system, but delete does not. What is this data? How do you allocate it? What is it used for?
|
Wil Renczes
Member #5,921
June 2005
|
Quote: Quote:
No, it does not need to know the size. The OS does, or the underlying allocation system, but delete does not. Sorry - poor wording on my part. I think we're getting at the same thing - when you delete an object, internally, delete derives the size of the allocation that's being freed since it knows the struct size of the class that's being deleted. But it still calls free() with a given byte size. And as William points out, void is not a type, so you can't call its destructor. Which brings me back to the problem: one shouldn't use a void pointer type in the first place. It's a skanky way to short-circuit a problem, and fraught with potential gotchas. Seriously: look at template classes. This is exactly what they're for:
Apologies in advance for the sparse example - I haven't run the compiler on this, so my syntax might be off somewhere, but you get the idea. The point is that you simply call delete on the node object now, since the compiler knows what T is when you instantiate the class - you're solid. |
NonLegato
Member #6,716
December 2005
|
Thanks everybody. Now I understand the concept of type safety and template. I think I'm going to read my old C++ book about data structure and algorithm again. |
Onewing
Member #6,152
August 2005
|
There are some good uses to void*. In my linked list class, I use void* to whatever data is to be stored in the list. You just have to cast it whenever you want to read/use the data. However, deleting a void* is a no-no in my books. I like to think of the void* as if pointing to something with my finger. I wouldn't want to delete my finger (ouch), I want to delete the something that it is pointing at. ------------ |
Murat AYIK
Member #6,514
October 2005
|
I never used void* since it didn't sound like something I would need, which also means I don't have any experience with it, but my programmer-sense says; if you create something whose size you will need later, then calc&store its size while you are creating it. _____________________________________________________ |
Goodbytes
Member #448
June 2000
|
Quote: Firstly, I don't think you can call delete on a void *. Delete needs to know the size of the allocated structure Typically, what happens is that C++ stores the exact size of the allocated memory block one word "before" the allocated memory block. For example: complex* c = new complex(1.0, -1.0); // say complex is a struct with two 4-byte floats // address 0xF0 0xF1 0xF2 // value 2 1.0f -1.0f // c == 0xF1 // size of allocated memory block (2 words) stored at 0xF0 char* str = new char[16]; strcpy(str, "Hello world!!!"); // address 0xF3 0xF4 0xF5 0xF6 0xF7 // value 4 Hell o wo rld! !!\0[?] // str == 0xF4 // size of allocated memory block (4 words) stored at 0xF3 Then when delete is called, it looks one memory space to the "left" of the allocated block to know how much to delete. This is how delete knows how much memory to free when given an array, even though you don't have to write delete[16] str;for example. Thus, requiring the type pointed to by a void* pointer is a matter of type safety re: which destructor to call, and has nothing to do with how much memory is actually being deleted. |
Fladimir da Gorf
Member #1,565
October 2001
|
Quote: There are some good uses to void*. In my linked list class, I use void* to whatever data is to be stored in the list. You just have to cast it whenever you want to read/use the data. That's not a good use for void*. That's where you should use templates to make the code type safe. And by the way, I bet no one can outperform STL in effiency, type safety and elegancy so why to invent the wheel over and over? OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
Onewing
Member #6,152
August 2005
|
Quote: That's not a good use for void*. That's where you should use templates to make the code type safe. It's worked for me so far. Maybe I'm thinking of template in more of a general definition and you have a more technical explanation. Care to share an example of what you mean? Quote: And by the way, I bet no one can outperform STL in effiency, type safety and elegancy so why to invent the wheel over and over? I don't doubt it. A lot of people tell me I'm "reinventing the wheel," but of course I am. I know there's a lot of things out there (like map editors, graphics libraries, etc.). It's not that I'm trying to make a better one or "reinvent" it, but rather understand it and learn from it. ------------ |
Fladimir da Gorf
Member #1,565
October 2001
|
Quote: It's worked for me so far. Maybe I'm thinking of template in more of a general definition and you have a more technical explanation. Care to share an example of what you mean? You're assuming that the linked list contains only objects of a specific type. But it doesn't have to (the compiler doesn't force type safety) and if one of the elements isn't of a desired type, you'll likely get a crash (or undefined behavior at best). Also what if you want to store ints, for example? You'd need one pointer dereference every time a value is accessed while that's not the case if you'd use a template. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
|
1
2
|