Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Array.Remove does not delete subArrays

Author
Message
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 30th Nov 2014 04:11 Edited at: 30th Nov 2014 05:00
I´ve discovered that Array.Remove does not delete subarray. (Arrays within types)

How do I make sure every subarray is deleted?

I´m using alpha 9 on mac

This code will show what I mean:


So, how to get rid of garbage?

I never want what I know.
MikeHart
AGK Bronze Backer
21
Years of Service
User Offline
Joined: 9th Jun 2003
Location:
Posted: 30th Nov 2014 09:45
AGK2 arrays are ZERO based. Means the index starts with 0. Btw. Length reports the last index, so you have to add 1 to get the actual length of the array.

This works I think:

Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 30th Nov 2014 10:26 Edited at: 30th Nov 2014 10:27
If you change the last for - next in your code to this:

for x=1 to 10
S2$=S2$+str(MyHouse[10].Room[x-1].Furniture)+Chr(10)
next

(MyHouse[10] instead of myHouse[9])

You will get two similar outputs.

an array.length of 10 is 11 elements. Length of 0 is 1 element. -1 is no elements. So if you want to fill up 1-10 you can use 1-10.

But why does it give similar output when changed to 10?

I never want what I know.
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 30th Nov 2014 11:11 Edited at: 30th Nov 2014 11:12
Ok - I found out that if you use array.remove agk will not clear the memory of the removed array, If you set the size of the array with array.lenght the data in the element will be as before



If I remove an element in the middle of the array and resize again wIth length agk will copy the element before or after into the new element.



I never want what I know.
MikeHart
AGK Bronze Backer
21
Years of Service
User Offline
Joined: 9th Jun 2003
Location:
Posted: 30th Nov 2014 11:47
You still didn't got it.

Zero based means having an index starting from 0 to length-1.

In your example you create a length of 10 items/indexes.

If you access your array with the index 10, you actually try to access the 11th index. Remove(9) removes the 10th index. Setting length=10 means you set your array to a length of 11 indexes. That is way your 11th is still the same.

The confusing part in AppGameKit is that length doesn't return the actual length of an array but the last index of the array which is the actual length-1.
MikeHart
AGK Bronze Backer
21
Years of Service
User Offline
Joined: 9th Jun 2003
Location:
Posted: 30th Nov 2014 11:48
An array with the length of 10 has to be accessed with indexes from 0 to 9.
JimHawkins
15
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 30th Nov 2014 12:16
Fundamentally, the word "length" is badly conceived. It isn't the length at all - it's the index of the highest element. Using length for this is confusing.

It's the equivalent of Pascal's High().

In Pascal, take an array with two elements (0 and 1 indices) called myArray:

High(myArray) returns 1
Length(myArray) returns 2
SetLength(myArray,20) will create a 20 element array [0..19]

Unfortunately, we're stuck with the muddled AppGameKit system!

-- Jim - When is there going to be a release?
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 30th Nov 2014 12:55 Edited at: 30th Nov 2014 13:58
I know that arrays are zero based. The manual for alpha 9 - the principles part says something about arrays in v2. Im not at my computer. But anyway. Why don't i get an error in my two last snippets when i fill 10 with data? It shouldn't exist...according to you...

THIS:

myarray as integer[10]
Myarray[10]=9887

do
print(myArray.length)
sync()
loop


does not create an out of bounds error...and it prints 10.....

I never want what I know.
JimHawkins
15
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 30th Nov 2014 13:58
It should give either an access violation or an array index out of bounds error, I think

-- Jim - When is there going to be a release?
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 30th Nov 2014 14:12
But this is what i'm saying. It doesnt. Declaring an array in v2 with "myarray as integer[10]" creates an array with 11 indexes from 0-10

I wish someone could run my 2 snippets in my second post to see what i mean.

I never want what I know.
JimHawkins
15
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 30th Nov 2014 14:26 Edited at: 30th Nov 2014 14:27
Here's an example to explain:



-- Jim - When is there going to be a release?
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 1st Dec 2014 10:30 Edited at: 1st Dec 2014 10:31
Oh my. I almost give up. Please read my answer and test my code snippet this time.

I KNOW that Length does not report the actual length of the array but the number of the last index. And I KNOW that Arrays start at ZERO.

PLEASE RUN this code snippet and check it out.


As you can see, after removing the last index and resizing again - in the final printout the old random number is back.
My question is. Why is the last index not zero in the final printout.

I never want what I know.
Hockeykid
DBPro Tool Maker
17
Years of Service
User Offline
Joined: 26th Sep 2007
Location:
Posted: 1st Dec 2014 11:13
Quote: "Why is the last index not zero in the final printout."


With AppGameKit V2, you can no longer count on variables being initialized to 0. This is much like lower level languages, such as C, C++, etc. Essentially, when a new variable is declared it points to a block of memory and picks up the value of whatever garbage is in it.

Since the memory for 11 indexes has already been allocated, the array doesn't "move" in memory when it gets shrunk. So when you readd another index to the array, it's picking up whatever "garbage" was left behind (in this case, your old value). However, if you expand the array it's likely (not always though) that it will find a new position in memory. This would result in your new values being initialized to 0.

Here's a modified version of your code that demonstrates this:


Technically it isn't a bug, as you should always be initializing your variables before you try to use them. However, since AppGameKit Tier 1 is BASIC this might be something that should get changed.


Sean

JimHawkins
15
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Dec 2014 12:39
Use myArray.insert instead of increasing the length

///MyArray.Length=MyArray.Length+1
MyArray.insert(99999)

Why would the compiler zero the memory if you simply increase the array length? I don't know of any compiler that will do that. It's up to the programmer to put sensible data into any new fields.

Dynamic arrays are really lists, and should be treated as such.

OOP systems will normally zero the fields of any newly-created object, but will not do that to non-object entities, which is what we are talking about here.

So I don't think this is a bug at all. It's doing what I think it should do.

-- Jim - When is there going to be a release?
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 1st Dec 2014 15:39 Edited at: 1st Dec 2014 16:17
@ Jim Hawkins, Hockey Kid

Thank you. Finally we are on track. And when you explain it like that I understand that no, it´s no bug, but only leftovers.

My problem with array.insert is that it does not allow Types. So you cannot write myArray.insert() like you can write MyArray.remove(). You have to give it a value.

This became a problem for me as I have three levels of types within types, so the easiest way to increase the indexes was to add a number to the length instead of initializing all my types within types with a default number. Sometimes I just want to add an index (new object) to set it up and then fill it with values later.

This won´t work:


The reason this became a problem for me was that when I deleted an object and it´s array in my editor and then created a new object. It would inherit some leftover values and behave strange. So I´m trying to be a clean and good programmer and prevent future bugs.

So the question now is - how to increase an array with types within types and make sure its content has no leftovers?

A command like copy or duplicate could be handy:
MyArray[0].duplicate( MyArray[MyArray.length] )

I could then use index zero as a template with default values and copy them to the newly created index

I never want what I know.
MikeHart
AGK Bronze Backer
21
Years of Service
User Offline
Joined: 9th Jun 2003
Location:
Posted: 1st Dec 2014 16:39
Quote: "My problem with array.insert is that it does not allow Types. "


Yes it does. I use it all the time without a problem. My guess is that you have the same problem like I had. I was expecting the array to store a reference to a type. So when you insert it into an array or retrieve it, you handle one particular UDT. But actually you are dealing with a copies. You store a copy. You retrieve a copy. When you change the copy, the udt inside the array isn't changed. And so on.

I worked around this by storing all UDTs or one type (like game objects for an example) inside an object array and store their indexes inside other arrays which I iterate through then.
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 1st Dec 2014 17:34 Edited at: 1st Dec 2014 17:37
@ MikeHart

Aahhh, thank you so much. I thought I had tested this out but it seems to have slipped my mind.

This code works:


I never want what I know.
JimHawkins
15
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Dec 2014 18:18
A lot depends upon the memory allocation and deallocation model in the runtime system. You wouldn't want to keep allocating new memory just because one field was added, or things get slow. Normally a default memory block is used., and when it's going to overflow new block of maybe twice the size is allocated on the smaller block copied in.

In Delphi the default allocation for a List is 16. But if you know you need lots you use myList.AllocBy(1024 or whatever). That way a new allocation will only happen when you have >1024 additions.

The big difference with OOP systems is that you can free it up when you've finished with it. I don't think this is possible in AppGameKit, which has a flat memory model.

-- Jim - When is there going to be a release?
Paul Johnston
TGC Developer
22
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 1st Dec 2014 18:48
Although you have found a way around your original problem, I will make remove() zero out the removed item so that when it is reused it does not cause confusion.
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 1st Dec 2014 21:46
@ Paul

Great! I learned a lot about arrays in this post, but, as you say, preventing confusion in Tier 1 and for beginners like me is probably a good thing.

And I think that the new array commands in v2, like array.length is much easier to handle than to always have to remember the zero factor. Length refers to the actual index you want to manipulate. So you don´t have to use the old -1 +1 thing.

Thank you, JimHawkins, MikeHart and Hockeykid for the patience and the help.

I never want what I know.
Hockeykid
DBPro Tool Maker
17
Years of Service
User Offline
Joined: 26th Sep 2007
Location:
Posted: 1st Dec 2014 22:03
Quote: "And I think that the new array commands in v2, like array.length is much easier to handle than to always have to remember the zero factor."


A temporary solution for now would be to create a new variable of "House" type and set the array index that you want to delete to your new variable and then delete the index.

Like this:




Sean

JimHawkins
15
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 2nd Dec 2014 01:09
Quote: "Although you have found a way around your original problem, I will make remove() zero out the removed item so that when it is reused it does not cause confusion."


Paul - That's kind of you. But I think it would be cleaner to zero the memory for any increase in the size (before applying new elements - as with insert). That is fairly normal practice.

It would be good to know how the memory allocation/deallocation works!

-- Jim - When is there going to be a release?
Paul Johnston
TGC Developer
22
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 2nd Dec 2014 02:13
Quote: "It would be good to know how the memory allocation/deallocation works!"


Setting the array.length will resize the array internal memory to that exact value, unless the internal memory is already that size, which is important in this case. New memory created by setting array.length will always be zeroed. insert() and remove() behave differently and will expand internal memory by 1.5x and reduce by 0.66x when limits are reach. New memory created by .insert() will also be zeroed.

So the remove() in this example reduced the length of the array by 1 but did not reduce the internal memory. When the array was then resized by increasing it's length by 1 (back to 10) AppGameKit looked at the array and saw the internal memory was already set at 10 so didn't touch it, and at no point was memory released or created so nothing got zeroed.
Timshark
17
Years of Service
User Offline
Joined: 30th Jun 2007
Location: Oslo, Norway
Posted: 2nd Dec 2014 18:18 Edited at: 3rd Dec 2014 04:39
I just want to end this Thread by making it clear for beginners that Creating an array in v2 of agk with
either

Dim MyArray[10] as MyType
or
MyArray as MyType[10]

Creates 11 indexes. From index 0 to index 10.
It does not, as stated in the earlier answers, create 10 indexes from 0 to 9

So to make it simple - with MyArray[10] you create index 1 to 10 - but also create an extra index at zero added in for you to use as you want. 0-10

I think this a very good thing because you don´t have to use the old -1 or +1 converting.

This is the manual for the new array commands:

http://www.appgamekit.com/documentation/guides/12_array_changes.htm

I never want what I know.
Native Tech
11
Years of Service
User Offline
Joined: 19th Jul 2013
Location:
Posted: 4th Dec 2014 10:27
U guys are awesome , this discussion has raised some good and bad points , however it is great to see all heads coming together to squash the issue and finally seeing Paul come with a remedy is good to see from TGC with AppGameKit , glad I backed this product

Native Technology

Login to post a reply

Server time is: 2024-11-25 11:20:28
Your offset time is: 2024-11-25 11:20:28