Results 1 to 10 of 10

Thread: Strange AV?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Strange AV?

    Hey everyone,

    I'm getting a strange AV. Don't really know why it's popping up.

    Code:
    type
      PMyRec = ^TMyRec;
      TMyRec = record
        Str: String;
        Int: Integer;
      end;
    
    procedure TForm1.Button5Click(Sender: TObject);
    var
      P: PMyRec;
    begin
      GetMem(P, sizeof(TMyRec));
      P^.Str := 'test';   //<< AV HERE!
      P^.Int := 5;
    
      FreeMem(P);
    end;
    This should go fine. I just set the Str which is actually a special kind of pointer, to point to 'test'.

    Can somebody enlighten me?

    Thanks
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  2. #2
    Hmm, strange, because only one line of code is wrong:
    Code:
    FreeMem( P );
    You must free String in record first, like this:
    Code:
    P^.Str := '';
    And only then call FreeMem.

    But... try to call FillChar( P^, SizeOf( P^ ), 0 ) after GetMem

  3. #3
    Hmm.. this is really odd. It does work if I replace getMem() and FreeMem() by New() and Dispose().

    Does anyone know the differences between these functions?

    I'll do some more testing ASAP. Thanks for your reply.

    Edit:

    Code:
      GetMem(P, sizeof(TMyRec));
      FillChar( P^, SizeOf( P^ ), 0 );
      P^.Str := 'test';
      P^.Int := 5;
    This works too. How is that possible?
    Last edited by chronozphere; 11-11-2010 at 07:16 PM.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  4. #4
    GetMem(P, sizeof(TMyRec));

    results in P, a chunk of allocated memory filled with crap. When you assign a string to this pool of crap you first have to free the old string. If it tries to free Nil then it won't try, but if there's any value but nil, then you are freeing something that isn't allocated

    Basically, you need to use either allocmem(it'll zero out the memory), or use fillchar after getmem. They are basically the same

    Edit: and I think new uses the same method as allocmem. Eg. zeroes before returning
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  5. #5
    PGDCE Developer de_jean_7777's Avatar
    Join Date
    Nov 2006
    Location
    Bosnia and Herzegovina (Herzegovina)
    Posts
    287
    new and dispose are used with pointers to records or other structures that contain automated types, so they are initialized/finalized properly. Since the string in your example is probably an ansistring, and therefore an automated type, you need to use new and dispose, which I suggest you use instead of getmem/freemem. I only use getmem/freemem for memory which has no type (e.g. plain pointers). As JSoftware said, the compiler will try to free the old string when it assigns the new one, but there is no old string, only garbage which was on the heap where your record got allocated.
    Existence is pain

  6. #6
    Code:
    Str: String;
    is merely a pointer.

    You should define strings with length if you want to use them in data blocks:

    Code:
    Str: String[64];
    I think this is will take 65 bytes but usable like normal string. Just that it can have at max 64 characters if defined like that. You can alternatively use array[1..64] of char;

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •