Thread: memory management...

  1. #16
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    New is good since it is a default way of allocating memory. You can make your own memory management system and then overload a class to use new (or delete) so that anyone else using your class can adapt to the change without learning any new syntax. New and delete are one of the advantages of the C++ langauge, not using them would be omitting part of the language. For example, I wouldn't say "I refuse to use the - sign for subtraction."

  2. #17
    Sayeh
    Guest
    You know, and this is just my humble opinion, but I think it's kind of pathetic to want a statement added to a language because a programmer is too lazy to write either a macro or a function to meet their needs.

    You only have to write it once because you can create your own libraries and headers, you know.

    I just think it's kind of lazy to expect the world to change around a laziness issue... I also think it introduces yet another layer of obfuscation to new programmers about what's actually going on.

  3. #18
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    sorry sayeh old chap this is one time when i will disagree with you. new and delete and their counterparts new[] and delete[] were necessary because malloc does not know about calling constructors and free does not know about calling destructors.Also making them operators rather than keywords gives us the possibility of overloading them to do memory management as necessary for your classes.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  4. #19
    Registered User zahid's Avatar
    Join Date
    Aug 2001
    Posts
    531
    I have just read all the posts.. It will be very helpfull.
    [ Never code before desk work ]
    -------------------------------------:-->
    A man who fears Nothing is the man who Loves Nothing
    If you Love Nothing, what joy is there in your life.
    =------------------------------------------------------= - I may be wrong.

  5. #20
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    are we allowed to type-cast pointers allocated with new/delete? i'd think so... also, i've noticed that sometimes i have multiple [seperate] allocations within the same scope with multiple pointers. to prevent having to have a complicated freeing scheme if an allocation fails at an intermediate allocation, i've decide to use but one pointer for the allocation/deallocation, and effectively segment it using seperate pointers. so far this seems to work out, since all of the pointers have the same base type [as does the master pointer]. however, if i reassign offset-ed addresses to offset pointers of different base types, [both signedness and data width], will this still work out? since the offsets are relative to the base type of the master pointer, i'll have to assign them such... and afterwards if using the offset pointers, they'll be relative to the base types of those respective pointers, correct? thank you.
    hasafraggin shizigishin oppashigger...

  6. #21
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    New and delete already know the type of the pointer thus eliminating the need or usefulness of typecasting with them. I don't know what new and delete will do if you actually find a way to re-type them via a typecast. Crashing your program is the first thing that comes to mind, especially if you are trying to change the type via a typecast.

    If you are returning a pointer to memory then you are using void *. This is what malloc returns, but not new. Even though new does use malloc for allocation it does not return void *. New returns a correctly typed pointer to the newly allocated object. It creates the object or can also instantiate a class. Here it is allocating 4000 signed bytes and returning a correctly typed pointer.

    char *Test=new char[4000];
    int *Test=new int[4000]

    This new returns char * not void *.
    Test has been intialized and created. No typecast needed.
    In the second one, 4000 integers are allocated - malloc(4000*sizeof(int)); or 8000 bytes.

    Invalid:
    char *Test=(unsigned int *)new char[4000];


    The left side does not match the right side so this will not be accepted by the compiler.
    This statement is not valid. You are telling the compiler to assign the character pointer Test to point to a character array (region of memory). However, the typecast is also telling the compiler that Test should be an unsigned int *, but new is saying char. This will flag an error in your compiler.

    Here new is instantiating a class which calls MyClass's constructor.
    Again, no typecast needed in this use or future uses of Test. It is already known.
    MyClass *Test=new MyClass;

    Since you use the datatype or class in the new statement, it is not correct to re-typecast the data type to a different type.

    If you are wanting a mem management like in Windows then your functions should return void *. Then it is up to the programmer what data type his pointer is and he can do this with typecasting.

    Code:
    char FAR *Text=0;
    HGLOBAL memhandle;
    memhandle=GlobalAlloc(GPTR,2048);
    Text=(char Far *)GlobalLock(memhandle);
    Left side matched right side - char FAR *Text=(char FAR *) - void FAR * has been typecasted to char FAR *. Now Text is a signed character pointer.

    GlobalAlloc will allocate the memory and return the handle to that area. To use it you must call GlobalLock to get a pointer to that area of memory. Here I've typecasted it to be a char FAR pointer -GlobalLock returns void FAR * so I can typecast it to whatever data type I want that memory to be.

    You could write similar functions - one that allocs the memory and returns a handle - that is tracked by your mem management system. Then you call another function to lock that area and return a pointer to it. In a non-multi-task environment you need not track which process that mem belongs to, just that it has been locked and allocated and cannot be moved or tampered with. Then you can typecast the void far * or in DJGPP just void * to be whatever data type you need. Cleanup is not as clean since the type is really not known by your functions, just by you. They are merely returning a void * pointer which points to an address unknowing of the data type.

    New and delete are much better and it might be beneficial for you to just override new and delete to get them to do exactly what you want. As long as you make destructors for each of your derived classes and for the base class, you should not have any problems with new and delete causing memory leaks.

    Delete will only fail when the system has been messed up by a wild pointer or it is used with a pointer that has not been allocated with new or when you try to delete a null pointer - not a good idea

    New will only fail if the system has been messed up by a wild pointer or if there is not enough memory for the object.

    In protected mode a wild pointer should not mess up your system or frag someone else's code. Your code will surely cease functioning, but everything else *should* be fine.

    I'm not sure about resizing memory areas with new - never had the need for it so I've never tried it. Pretty sure that since the object has already been created and init that this is not allowed. You must delete the pointer and realloc with the new size of the object.

    Give me a better idea of what you want with this mem management thing and I'll help you code it. We've been through this mem thing a lot and perhaps I'm misunderstanding you - would love to help. Promise that I'll think outside of the box - just this once.

  7. #22
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    Code:
    /***************************** fuzz ********************************************
    
    This function takes coordinate parameters and fuzzes the graphics display.  It
    his perhaps the slowest of all graphics functions in this program.
    
    *******************************************************************************/
      
      vo OUTPUT :: fuzz (un xl, un yl, un xh, un yh)
      {
        un *master_buffer;
        un *r_add_table,
           *g_add_table,
           *b_add_table,
           *div_table;
    
        un alloc_size = (yh - yl) * (xh - xl);
    
        //  allocate the master buffer
        if ( (master_buffer = (un *) calloc (alloc_size * 4, 4)) == NULL) return;
    
        r_add_table = master_buffer + 0 * alloc_size;
        g_add_table = master_buffer + 1 * alloc_size;
        b_add_table = master_buffer + 2 * alloc_size;
        div_table   = master_buffer + 3 * alloc_size;
        
        //  add the buffers
        for (un u0 = 0; u0 < yh - yl; u0++)
          for (un u1 = 0; u1 < xh - xl; u1++)
          {
            un pix_add = h.vb.g_pixel (u1 + xl, u0 + yl);
            uc r, g, b;
    
            //  over line flow, reword...
            r = (pix_add >> (h.vb.vars.g_bpp + h.vb.vars.b_bpp)) & h.vb.vars.r_max;
            g = (pix_add >>                    h.vb.vars.b_bpp ) & h.vb.vars.g_max;
            b = (pix_add >>                    0               ) & h.vb.vars.b_max;
    
            //  add the original pixel to the add buffers
            *(r_add_table + u0 * (xh - xl) + u1) += r;
            *(g_add_table + u0 * (xh - xl) + u1) += g;
            *(b_add_table + u0 * (xh - xl) + u1) += b;
            *(div_table   + u0 * (xh - xl) + u1) += 1;
    
            //  add up the rgbs to random adjacent/on pixels
            for (un u2 = 0; u2 < 8; u2++)
            {
              un x_t = u1 + (rand () % 3) - 1,
                 y_t = u0 + (rand () % 3) - 1;
    
              if ((x_t < (xh - xl)) &&
                  (y_t < (yh - yl)))
              {
                *(r_add_table + y_t * (xh - xl) + x_t) += r;
                *(g_add_table + y_t * (xh - xl) + x_t) += g;
                *(b_add_table + y_t * (xh - xl) + x_t) += b;
                *(div_table   + y_t * (xh - xl) + x_t) += 1;
              }
            }
          }
        
        for (un u0 = 0; u0 < yh - yl; u0++)
          for (un u1 = 0; u1 < xh - xl; u1++)
          {
            un offset = u0 * (xh - xl) + u1;
    
            *(r_add_table + offset) /= *(div_table + offset);
            *(g_add_table + offset) /= *(div_table + offset);
            *(b_add_table + offset) /= *(div_table + offset);
          }
    
        for (un u0 = 0; u0 < yh - yl; u0++)
          for (un u1 = 0; u1 < xh - xl; u1++)
            P_PIXEL (xl + u1, yl + u0,
              *(r_add_table + u0 * (xh - xl) + u1),
              *(g_add_table + u0 * (xh - xl) + u1),
              *(b_add_table + u0 * (xh - xl) + u1));
    
        h.vb.update (xl, yl, xh, yh);
    
        free (master_buffer);
    }
    if i used new/delete with this, could i have rgb/div-table have different base types, and be assigned to point to offsets of master_buffer?

    PS, i thought this gaussian-style blur would be faster then doing it unwound per-pixel, but nope. i guess the same number of calculations are made either way. so, it's asm for me... fortunately i have AoA to read, 1.4k pages... yum...
    hasafraggin shizigishin oppashigger...

  8. #23
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Assembly is very easy, especially if you read AoA. You will be amazed at how much power is packed into so few opcodes. And when you learn it well enough you will be able to do super fast graphics and pretty much super fast anything. Make sure you do a thorough read of it - expecially the chapter on Von Neumann arhitecture and CPU architecture. When you know how it all fits together you can create code that is much faster simply because it is working with the machine instead of against it. Excellent resource that AoA.

  9. #24
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Now I see what you are doing. It is a simple bi-linear interpolation only you are doing it a bit different. Actually the bi-linear interpolation will be much faster than doing it the way you have been. No for loops, instead you will be calling your bilinear function for x,y,x+1,y+1 for RGB. This does cause 3 new stack frames to be set up in the calls - make sure your bilinear function is inlined and in pure asm (use the FPU). The inline should help a bit.

  10. #25
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    also note that my fuzz isn't uniform indirection. [giving it a 'dirty fuzz'] which means my asm arithmetic sequence would be variable. i have some more ideas to try out, so we'll see...

    and aside from the speed... again...

    if i used new/delete with this, could i have rgb/div-table have different base types, and be assigned to point to offsets of master_buffer?
    hasafraggin shizigishin oppashigger...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. tools for finding memory leaks
    By stanlvw in forum C++ Programming
    Replies: 4
    Last Post: 04-03-2009, 11:41 AM
  2. Replies: 7
    Last Post: 02-06-2009, 12:27 PM
  3. Valgrind says I suck at memory management :)
    By carrotcake1029 in forum C Programming
    Replies: 6
    Last Post: 02-01-2009, 08:10 PM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. Managing shared memory lookups
    By clancyPC in forum Linux Programming
    Replies: 0
    Last Post: 10-08-2003, 04:44 AM