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.

DarkBASIC Professional Discussion / Weird Bug when using Arrays and Pointers

Author
Message
ShellfishGames
13
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 9th Jul 2014 17:43 Edited at: 9th Jul 2014 17:45
Might be worth a bug report, but I've got hardly any information on how this happened and how it can be reproduced, so for now I'm posting here instead..

In one of my projects, this line of code caused an array out of bounds crash:

*p = (*p) - pixel_type(1).collision

"Array does not exist or array subscript out of bounds at [that line]"


So for debugging purposes I did this:



The message returns 1024, which is the size I used when setting up the pixel_type() array. So accessing element 1 of that array shouldn't cause any problems, right?
Well, apparently it is, since the Success message was never displayed. But - as it turned out - this works just fine:






Does anybody have a clue what's going on here? I guess it must have to do something with the fact that the calculation contains pointers, as I use them relatively rarely and never had such a bug before.

Note: Using DBP 7.61. The error occured as well after setting SafeArrays=No within the compiler's setup.ini file (well, not that error message, the program just crashed as you would expect).
I'd rather not upload the whole code, as it's quite a lot and I wasn't really planning on going open source with the project. But still, thought I might share yet another funny story of how the DBP compiler messes up in random situations.

ShellfishGames
13
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 9th Jul 2014 18:00 Edited at: 9th Jul 2014 18:05
OK... it seems to be one of that strange horrible scenarios where everything just stops working in very weird ways. I had that with one or two projects before (on different computers, with different DBP versions and completely different codes).

Another function:



It crashes with a memblock position out of range error for the memblock dword(pixelmap(map).mem, 12+off2) part. So naturally I want to try to find out why exactly it crashes and output the function parameters at the start of the function in order to figure out what parameters cause the crash.
Well, what can I say, the output itself results in the crash not happening again. But no, that's not the end of the story, even putting this line at the start of the function:

tmp$ = "Swapping"

..solves the problem. However, other strings don't.
So what it comes down to is that this:



works fine, but this:



does not. I narrowed it down even further and got to the following conclusion:

Assigning tmp$ any string with 8 or more characters solves the problem. The program works. If I don't assign it any value, or use a string with 7 or less characters, I get the memblock position outside range error a few lines below. Unfortunately, this is not a joke.

Any input on what could cause these weird problems and how to solve them would be greatly appreciated.


Edit: Just an idea.. is it possible that assigning a value to the string variable affects the future output of rnd() in some way? That, again, would be very weird, but the only possible explanation of what I just witnessed that occured to me so far.

TheComet
18
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 9th Jul 2014 18:12 Edited at: 9th Jul 2014 18:13
Are you in any way accidentally overwriting memory locations you shouldn't be (buffer overflow or whatever you want to call it)? The symptoms you describe would accurately fit to that.

I suggest you get the following code running in a new, clean project:


See if you can reproduce the error in a small test program. If you are able to, post it here. If not, then we can conclude that the error is somewhere else in your program.

ShellfishGames
13
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 10th Jul 2014 14:56
Well, that was easier than expected.



This way it works for me, but once I use the line that is commented out instead of the two using the tmp variable, it crashes in just the same way as depicted in the original post.

Could anybody confirm that this code results in a crash?



And correct me if I'm wrong - but I don't think in this code there's anything wrong with the usage of pointers. It just writes to memory locations that were allocated before.

TheComet
18
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 10th Jul 2014 17:54 Edited at: 10th Jul 2014 17:56
Not near a DBP compiler right now, and I've only used pointers in C/C++, but here's what I see (correct me if I'm wrong).



p is pointing to 32 bytes of memory, yes? Good.



pixel_type(x).collision is a boolean (internally DBP stores bools as 1 byte, as can be seen with this here:
).



Here, you are trying to subtract a boolean (1 byte) from some random chunk of memory. I'm going to assume DBP doesn't know how to do that without some extra context, which is why it crashes.



It baffles me that this even works. Pointers in DBP are context sensitive. Pointers don't know what data they're pointing to, and neither does the data being pointed to. It's just a collection of bytes.

For example:


Both tmp and tmp# are reading from the same raw memory. The difference is that tmp is casting the raw memory to be an integer, and tmp# is casting it to be a float. The result? Different numbers.

What you should be doing:


Now, I have questions.

1) Why on earth would you use make memory for storing something that as far as I can see is a simple array of integers? DBP won't be able to know what type the value pointed to is, so any arithmetic you do with it, DBP will make assumptions on it based on its context. You should be using insert array at bottom and all of those other commands for array manipulation.


2) Does make memory even initialise the memory, or is it just random junk? I.e. if the following code doesn't print 0 then you have a problem.


ShellfishGames
13
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 10th Jul 2014 19:39 Edited at: 10th Jul 2014 19:45
If I define the collision attribute as integer, it results in the same error (array out of bounds), so I assume it isn't related to the data type. (Generally DBP has no problem with mixing up integers and booleans due to implicit type conversion)
The way I see it, DBP simply assumes that pointers always refer to integers. For instance:



x and x# hold the same values afterwards (which is far from similar to 0.5). When writing (in line 2), it takes the bit representation of the float 0.5 directly, but when reading from *p, it always takes the integer interpretation and then converts it to float, if required. So using pointers to store float values is just not quite possible in DBP the way I see it. Hence I usually use funny workarounds for these cases, like using a 4 byte memblock and something like "write memblock float mem, 0, x# : tmp = memblock dword(mem,0) : *p = tmp". Which is horrible, but it works.

Edit: I have to correct you at this point.

Quote: "Both tmp and tmp# are reading from the same raw memory. The difference is that tmp is casting the raw memory to be an integer, and tmp# is casting it to be a float. The result? Different numbers.
"


This is in fact not the case. tmp and tmp# will be identical (tested it), because, as I stated above, reading from pointers apparently always returns the integer value and then casts it to whatever data type the value is assigned.


To answer your questions:

2) It's true that make memory does not initialize the memory by setting it to 0 or anything like that. I do that manually when required.

1) The reason why I'm using make memory is that I need a dynamic number of those arrays, each of which has to be assigned to one element of an array using a user defined type. This is hardly possible with DBP arrays as they are always global and referred to by name rather than by ID. One alternative would be using memblocks, but as far as I remember there's just a limited number which can be used within a program, but I might potentially need hundreds if not thousands of those lists. And lastly, I simply assumed the direct memory access would be faster than using arrays (which are basically linked list, hence generate quite a bit of overhead, if I am not mistaken?).

Of course the simple crash example from above could be solved by simply using an array. However, in my original project, that's not a possible alternative.

Login to post a reply

Server time is: 2026-07-06 04:29:26
Your offset time is: 2026-07-06 04:29:26