Thread: Access Violation Of Memory Buffer WHY??

  1. #16
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Perhaps the buffer is not lockable. If this is the back buffer then you must set correct flags for the buffer to be locked. Otherwise Lock() is guaranteed to fail.

    Also most surfaces are not lockable. The whole premise behind Direct3D is to eliminate direct accesses to the buffer. Basically you would use DrawPrimitive() to render textures instead of rendering yourself. Also the texture stages are used to do multi-texturing and other effects, but notice you never really get to physically 'touch' the surface in your code.

    I've also done some assembly programming with DirectX buffers and I can tell you that they are not as they appear. For instance:

    Code:
    ...
    bufferoffet=0;
    for (int i=0;i<height;i++)
    {
    Buffer.ptrBuffer[bufferoffset]=color_value;
    bufferoffset+=Buffer.Pitch;
    }
    ...
    This works in C/C++ but not in assembly, barring the Buffer structure here in assembly. Assume that ptrBuffer is a pointer to a valid Direct3D buffer that has been locked.


    Code:
    ...
    START:
    mov edi,ptrBuffer
    xor	edx,edx
     
    RENDER: 
    mov eax,colorvalue
    stosd
    ;account for DWORD we just wrote
    sub edi,4
     
    ;move down one line
    add edi,BufferPitch
     
    ;increment height counter
    inc edx
     
    ;test for end of loop condition
    cmp edx,0
     
    ;if edx!=0 (ZF=0) then short jump to RENDER label
    jne RENDER
    ...
    ...
    But this does not work. You will get several small images if you do this. My assumption was since you are using Buffer.Pitch or BufferPitch as the width of the buffer then it must already be shifted left by the correct value to account for writing DWORDs and not BYTEs. However, this is not the case. In order for the code to work, barring any other errors, you must

    Code:
    ...
    ;use ebx which hasn't been used yet
    mov ebx,BufferPitch
     
    ;multiply by 4 -> hence 4 bytes per DWORD..BufferPitch doesn't account for this?????
    shl	 ebx,2
    add	edi,ebx
    ..
    But if you multiply BufferPitch by 4 in C you will get a very nast mess on screen and more than likely crash hard.
    Last edited by VirtualAce; 08-12-2004 at 07:59 AM.

  2. #17
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>the if statement right at the beginning of the code should catch it and then the loop should be broken

    Well, the way your message loop is set up, the DirectDraw code will still get executed after each message is processed - meaning that even if WM_QUIT is posted from WM_DESTROY, the DirectDraw code will be executed at least once before the WM_QUIT is received, depending on how many messages are waiting in line before the WM_QUIT. To (partially?) fix that (so that all currently queued messages will be handled before the DirectDraw code is executed), you can put all the DirectDraw code in an else{} block after the if(PeekMessage()), like I mentioned above. I'm not totally sure if the WM_QUIT will be guaranteed to appear in the message queue exactly when you call PostQuitMessage() though, since I'm not familiar with the internal workings of the Windows messaging functions. You'll have to ask the gurus here about that

    **EDIT**
    >>Lock() is guaranteed to fail.
    In which case, the program would crash on startup as opposed to exit, like I mentioned before

    >>The whole premise behind Direct3D
    Again, this is DirectDraw... Remember 'lpddsPrimary'? => 'Long Pointer to DirectDraw Surface Primary'
    Last edited by Hunter2; 08-12-2004 at 09:48 AM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #18
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Bubba
    Yep, I knew that looked suspicious and almost posted that was the problem. Salem is correct, you are destroying the pointer to your surface therefore it is NULL when you attempt to write to it. Very bad thing.
    No, that variable can and should be zeroed out because it only recieves information about the surface from the Lock function.
    Quote Originally Posted by Bubba
    Also most surfaces are not lockable.
    This is not Direct3D, it's DirectDraw.
    Quote Originally Posted by Hunter2
    Well, the way your message loop is set up, the DirectDraw code will still get executed after each message is processed - meaning that even if WM_QUIT is posted from WM_DESTROY
    You are correct. Simply adding a test condition for Lock will solve the problem.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  4. #19
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Oh right. When DestroyWindow gets called, the window gets destroyed (... yes, duh lol). If the surface has any association with the window at all (i.e. a clipper, perhaps) it is probable that you will be unable to draw to it anymore, thus causing Lock() to fail.

    bartybasher, are you using DestroyWindow() to shutdown your application, or is it called somewhere along the line? If it is, try rearranging your shutdown sequence in some way so that it gets called after all the directdraw is cleaned up. I think this is the same problem that I had a while back.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #20
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    That makes a lot of sense now. You see my message handler waits for the WM_DESTROY message before telling the code to quit. So therefore yes DirectDraw will try and write to nothing.
    So I tested this by changing the message from WM_DESTROY to WM_CLOSE and it works perfectly.
    Thinking about it all I would really need to do is to take the test for WM_QUIT out of the first if block and put it underneath it. That way the program would catch it before the direct draw code could run.

    Many Thanks Everyone!!!!

  6. #21
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    No, that variable can and should be zeroed out because it only recieves information about the surface from the Lock function.
    Yes I was thinking of something else when I wrote that. I do not use DirectDraw anymore rather I render directly into the swap chain in Direct3D if I'm doing direct buffer access programming.



    Using DirectDraw interfaces is deprecated and should not be relied upon even though technically they are still there. Direct3D provides a much better way of accessing the hardware buffers.

    DirectDraw is no more. They are both merge into DirectGraphics. I would not touch DirectDraw since the same functionality can be gained from Direct3D.

    And no...all surfaces are not lockable at all times. Locking numerous surfaces causes sever performance issues and it also looks as though you are writing directly to the primary buffer which is not good. You should be writing to the secondary buffer then when it flips it will display the secondary on the primary and/or flip it depending on your mechanism.

    So even though you fixed that problem...you still are going to run into several others if you insist on using DirectDraw instead of Direct3D.
    Last edited by VirtualAce; 08-13-2004 at 07:36 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Access violation... can't figure it out...
    By Raigne in forum C++ Programming
    Replies: 7
    Last Post: 10-11-2007, 10:52 AM
  2. access violation in int array
    By George2 in forum C Programming
    Replies: 2
    Last Post: 08-02-2007, 11:28 PM
  3. Access violation when reading a string.
    By Desolation in forum C++ Programming
    Replies: 16
    Last Post: 05-01-2007, 10:25 AM
  4. how to access memory
    By zhu_dave in forum Tech Board
    Replies: 7
    Last Post: 01-10-2007, 06:57 AM
  5. Strange access violation
    By jimmy_anttila in forum Windows Programming
    Replies: 2
    Last Post: 04-11-2004, 03:10 AM