[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gm2] double free or corruption with pointers
From: |
Fischlin Andreas |
Subject: |
Re: [Gm2] double free or corruption with pointers |
Date: |
Thu, 5 Aug 2010 09:44:35 +0000 |
But you can easily do this yourself. It is just a few statements more:
IF runtimeSize < maxArraySize+1 THEN
..
ix := 3;
IF ix <= runtimeSize THEN
myArray^[ix] :=
ELSE
(* raise error *)
END(*IF*);
BTW, you should also test the success of Storage.Allocate before using myArray^
with some index such as 3.
But to be frank, I believe you need to get away from this primitive test code
to really get something more useful. You need to profit from the abilities of
Modula-2 and design a module that does what you want.
You need a data structure of following kind used only within an implementation
module and export the type as opaque. Within the module you need a following
object
CONST
maxArrEles = 32768;
TYPE
IntegerArray = RECORD
ints: ARRAY [0.. maxArrEles-1]
OF INTEGER;
curNoOfArrEles: INTEGER;
END;
then you need some methods operating on this and please do not call this an
open array, it is a dynamic integer array only. I suggest you start from a DEF
similar to the following:
DEFINITION MODULE IntArrays;
(*******************************************************************
Module IntArrays (Version 1.0)
Purpose Management of dynamic integer arrays
Remarks Maximum storage size is platform and compiler dependent
Programming
o Design
Andreas Fischlin 08/05/2010
ETH Zurich
Systems Ecology
CHN E 21.1
Universitaetstrasse 16
8092 Zurich
SWITZERLAND
URLs:
<mailto:address@hidden>
<http://www.sysecol.ethz.ch>
<http://www.sysecol.ethz.ch/SimSoftware/RAMSES>
Last revision of definition: 08/05/2010 AF
*******************************************************************)
TYPE
IntArray;
VAR
notAllocatedIntArray: IntArray;
(*
Read only variable which may be used for variables of type
IntArray to denote that no memory has yet been allocated for
that IntArray, i.e. AllocateIntArray has never been called. It is a
good programming practice to assign this value to all IntArray
variables during the initialization phase.
*)
undefInteger : INTEGER; (* READ ONLY; = MIN(INTEGER)+1 *)
PROCEDURE AllocateIntArray(VAR ia: IntArray; length: INTEGER);
(*
Allocate memory to store integer array ia, a reference is returned
pointing to the string which is NIL if no more memory is available.
Each element of the integer array are is set to the value undefInteger.
*)
PROCEDURE IntArrayExists(ia: IntArray): BOOLEAN;
(*
Returns TRUE if storage has been allocated for IntArray
ia.
*)
PROCEDURE DeallocateIntArray(VAR ia: IntArray);
(*
Dispose of memory which has been allocated for IntArray
ia.
*)
PROCEDURE IntArrayLength(ia: IntArray): INTEGER;
(*
Returns currently available length for IntArray
ia. If ia does not exist, returns 0.
*)
PROCEDURE SetIAEle(ia: IntArray; ix: INTEGER);
(*
Stores the ix'th element in ia. If ia does not exist, the procedure
does nothing.
*)
PROCEDURE IAEle(ia: IntArray; ix: INTEGER): INTEGER;
(*
Returns ix'th element of ia. If ia does not exist, it returns undefInt.
*)
END IntArrays.
Hope this gets you going.
Regards,
Andreas
ETH Zurich
Prof. Dr. Andreas Fischlin
Systems Ecology - Institute of Integrative Biology
CHN E 21.1
Universitaetstrasse 16
8092 Zurich
SWITZERLAND
address@hidden
www.sysecol.ethz.ch
+41 44 633-6090 phone
+41 44 633-1136 fax
+41 79 221-4657 mobile
Make it as simple as possible, but distrust it!
________________________________________________________________________
On 03/Aug/2010, at 11:45 , Martin Kalbfuß wrote:
> Many Thanks,
>
> MODULE array;
>
> IMPORT Storage, SYSTEM, STextIO, SWholeIO;
>
> CONST maxArraySize = 32768;
> TYPE DynArrayPtr = POINTER TO ARRAY[0..maxArraySize] OF INTEGER;
> VAR myArray : DynArrayPtr;
> VAR runtimeSize : INTEGER;
>
> BEGIN
> runtimeSize := 5;
> Storage.ALLOCATE(myArray, SYSTEM.TSIZE(INTEGER)*runtimeSize);
> myArray^[3] := 5;
> SWholeIO.WriteInt(myArray^[3], 1);
> STextIO.WriteLn();
> Storage.DEALLOCATE(myArray,SYSTEM.TSIZE(INTEGER)*runtimeSize);
> END array.
>
> This works like I need it. But the boundaries aren't checked any longer
> like they are for static arrays. :-(
>
>
> Am Montag, den 02.08.2010, 17:34 +0000 schrieb Fischlin Andreas:
>> Dear Martin,
>>
>> I see many problems with your code:
>>
>> NEW(myArray, 6, 6)
>>
>> is not a legal ISO statement, since you use it for a pointer type. Then the
>> only additional legal argument to 'myArray' would be the tag in case that
>> the record to which the pointer points is of the variant case kind. But that
>> is not the case in your situation.
>>
>> You seem to want to program almost in assembler. But I don't see the need,
>> since you could easily write
>>
>> CONST noOfArrEles = 6;
>> TYPE DynArray = ARRAY [0.. noOfArrEles-1] OF INTEGER;
>> DynArrayPtr = POINTER TO DynArray;
>> VAR myArray: DynArrayPtr;
>> ...
>> NEW(myArray, TSIZE(INTEGER)*noOfArrEles);
>> or even safer
>> NEW(myArray, TSIZE(DynArray));
>>
>> I am still a bit confused about the fact that I am not sure you really want
>> to allocate even a two dimensional integer array. However, above code could
>> be easily expanded accordingly.
>>
>> This code is more Modula-2 like and should accomplish the same in a more
>> legal manner.
>>
>> Regards,
>> Andreas
>>
>>
>> ETH Zurich
>> Prof. Dr. Andreas Fischlin
>> Systems Ecology - Institute of Integrative Biology
>> CHN E 21.1
>> Universitaetstrasse 16
>> 8092 Zurich
>> SWITZERLAND
>>
>> address@hidden
>> www.sysecol.ethz.ch
>>
>> +41 44 633-6090 phone
>> +41 44 633-1136 fax
>> +41 79 221-4657 mobile
>>
>> Make it as simple as possible, but distrust it!
>> ________________________________________________________________________
>>
>>
>>
>> On 01/Aug/2010, at 11:55 , Martin Kalbfuß wrote:
>>
>>> Hi! The following program ends up with a double free corruption. I'm not
>>> sure how this can happen. Anything wrong with my code?
>>>
>>> MODULE test2;
>>>
>>> IMPORT SYSTEM, SWholeIO, STextIO;
>>> FROM Storage IMPORT ALLOCATE, DEALLOCATE;
>>>
>>> TYPE DynArray = POINTER TO INTEGER;
>>> VAR myArray : DynArray;
>>> elementPtr : DynArray;
>>> BEGIN
>>> NEW(myArray, 6, 6);
>>> elementPtr := SYSTEM.ADDADR(myArray, 2*5+3);
>>> SWholeIO.WriteInt(elementPtr^, 1); STextIO.WriteLn();
>>> DISPOSE(myArray);
>>> END test2.
>>>
>>>
>>> Thanks,
>>> Martin
>>>
>>>
>>> _______________________________________________
>>> gm2 mailing list
>>> address@hidden
>>> http://lists.nongnu.org/mailman/listinfo/gm2
>>
>
>
>
> _______________________________________________
> gm2 mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/gm2