#100734 - pkwong - Wed Aug 30, 2006 4:50 am
i'm using a linked list to store key effects and remove them when the keyup. but for a weird reason, when i press the 8th button(either 8), both the emulator and DS freezes.
Code: |
//add
for (int i=0; i<8; i++){
if (pressed & keys[i]){
keyEffects.push_back(new keyEffect(i));
}
}
//remove
for (int i=0; i<8; i++){
if (released & keys[i]){
list<keyEffect* >::iterator It=keyEffects.begin();
for (;It!=keyEffects.end() && (*It)->getChannel()!=i; It++);
delete *It;
keyEffects.erase(It);
}
}
|
i thought it was the class's problem
however, when i put around 10 lines of "new anotherClass();" at my init(),
it also freezes.
am i using too much RAM so that it hangs...?
my program is so small now that it had only 2 class, and that just hold a few "short" which shouldn't take up too much mem.
the biggest part of the program comes from the grahpics, i included them as .c files. is this a bad way to include them?
#100748 - !cube - Wed Aug 30, 2006 8:24 am
Are you sure that the "keys" array is long enough and does actually hold 8 indexes?
As a side note, you should use ++it instead of it++ because the postfix increment/decrement operators allocate a new object from the stack instead of only accessing the object on which the operator was called.
#100755 - pkwong - Wed Aug 30, 2006 9:17 am
the keys array is long enough
the weird thing is that it also happens at the code at other place.
their common is that it hangs when creating new instance of a class...
so i suspect that there's not enough ram left for me...
have any other ppl tried this before?
#100756 - dXtr - Wed Aug 30, 2006 9:18 am
I'm not sure if it really is your problem.. but I'm guessing all the dynamic allocation/freeing of memory will fragment the memory and cause problems in the end
_________________
go back to coding and stop screaming wolf :)
#100758 - pkwong - Wed Aug 30, 2006 10:23 am
that's really bad
seems like i have to them statically...
#100761 - agentq - Wed Aug 30, 2006 12:00 pm
Memory fragmentation? You serious? You have 4Mb of RAM and a handful of classes of only a few bytes. Memory fragmentation will never be an issue.
The first thing that occurs to me is that you shouldn't havn't constucted your for loop properly:
Code: |
//remove
for (int i=0; i<8; i++){
if (released & keys[i]){
list<keyEffect* >::iterator It=keyEffects.begin();
for (;It!=keyEffects.end() && (*It)->getChannel()!=i; It++) {
delete *It;
keyEffects.erase(It);
}
}
}
|
#100769 - pkwong - Wed Aug 30, 2006 12:58 pm
thanks for pointing out.
i think i need a better coding style :P
i see that other ppl are having malloc problems which returns a used memory
could this be somehow related?
#100771 - !cube - Wed Aug 30, 2006 1:17 pm
What's in the keys-array anyway? I seriously doubt it's a memory management issue rather than just a logic error in the code. You're running the code on ARM9 right?
Agentq, the code you wrote is incorrect since the point is not to delete all the objects but just the one where the iterator points to after going through the vector.
#100775 - pkwong - Wed Aug 30, 2006 1:53 pm
here's the code for the keys:
Code: |
int keys[]={KEY_L, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_Y, KEY_X, KEY_B, KEY_A};[ |
used array coz i want to do key config later
also, here's my class definition
Code: |
class keyEffect{
public:
keyEffect();
keyEffect(short channel);
~keyEffect();
short getChannel(){return channel;}
private:
short channel;
short spriteID[5];
short count;
}; |
and yeah, i'm running the code in ARM9.
#100778 - !cube - Wed Aug 30, 2006 2:14 pm
pkwong wrote: |
here's the code for the keys:
Code: | int keys[]={KEY_L, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_Y, KEY_X, KEY_B, KEY_A};[ |
|
Well there's your problem..
The check in your code:
Code: |
if (pressed & keys[i]) |
will always be true whenever pressed is true. If you do the check in VBLANK or in an IRQ, you'll end up allocating and pushing an enormous amount of keyEffect instances into the vector and eventually run out of memory. The removal has the same bug and will delete everything from the vector every time.
#100781 - dXtr - Wed Aug 30, 2006 2:21 pm
agentq wrote: |
Memory fragmentation? You serious? You have 4Mb of RAM and a handful of classes of only a few bytes. Memory fragmentation will never be an issue.
|
well.. as I didn't get what his code was suppsoed to do I thought I mention that it _could_ be a problem (I never said that it definetly was that who caused the problem..). all I wanted to lift up was that he should be more sparse with the memory. but enough of that..
_________________
go back to coding and stop screaming wolf :)
#100783 - pkwong - Wed Aug 30, 2006 2:27 pm
oops, sorry...
forgot to say
i used "int pressed = keysDown();" to get the keys
so that shouldn't happen, right?
#100786 - !cube - Wed Aug 30, 2006 2:54 pm
In that case if you do the checks in VBLANK, having a key pressed down will create a new instance of keyEffect and push it in the vector 60 times per second. Do you run that code in VBLANK or in an interrupt or where?
#100793 - pkwong - Wed Aug 30, 2006 4:59 pm
ya, but should that be the difference of keyHeld() and keyDown()?
i saw in the examples that
"int pressed = keysDown(); // buttons pressed this loop"
i put the code in VBLANK and i checked dualis that it's not creating new sprites(i creates sprites in the constructor), so i think this should not be the problem. thanks for helping~
#100877 - agentq - Thu Aug 31, 2006 9:45 am
Hang on, if you're creating the object in the Vblank, you could run into quite a few problems. I don't think the memory manager is interrupt safe, so if you happen to allocate memory in the interrupt handler and in the main program at the same time, you could cause a crash.
Also, as a general rule, you should always try and minimise time spent in the interrupt handler, as other interrupts could be delayed if the interrupt takes too long to execute.
But, more generally, calling the memory manager to allocate space for each keypress is a bit wasteful on processing time, and pretty much unnecessary, as dXtr said. Each 'new' call is probably padded to 16 bytes (or sometimes more) and so the objects will probably take up a lot more memory than you expect.
If you want the syntactic convinience of using 'new', you could override the operator and allocate your object from a static pool of 8 or so items.
Hope this helps you a bit.
#100908 - pkwong - Thu Aug 31, 2006 5:47 pm
(sorry for the bad topic name, thanks for editing it)
woo~ thanks!
i learn much more about the DS from all of you
agentq:
you're right, creating a new instance for each new keypress is a waste of time...i fixed it with using an array of 8 keyEffect. ^^
but i'm still a bit curious about why i got this problem...
i just had another test on my code.
Code: |
int main(void) {
powerON(POWER_ALL_2D);
for (int i=0; i<999; i++)
new int();
........
|
wow, it hangs right after i press run in the emu.
then i used TouchTest from the examples as a template, did the same thing, it doesn't even hang if i run it for 9999 times.
it made me think of the graphics i included. that's the only difference i can spot.
the graphics are in .c format and have 2 files for 1 graphic, gfx data and palette, total around 5xxKB text.
e.g.
Code: |
const unsigned char wbar_Sprite[4096] __attribute__ ((aligned (4))) = {....} |
Code: |
extern unsigned char wbar_Sprite[4096]; |
is it a big problem?
actually, should i post all my code?
#100989 - pkwong - Fri Sep 01, 2006 11:53 am
lol!
guess what, after remove 1 single line, everything went back normal
bool end=FALSE;
i got a "bool start=FALSE;"
both are global (i know i shouldn't)
removing "start" doesn't help...
want to replicate this funny thing?
use "combined" template from the examples,
change the arm9 source to cpp
add
in the global area, and then put
Code: |
for (int i=0; i<9999; i++)
new int();
|
in int main()
run it in the emu or HW, it hangs~ remove the line and try again, it works!
i'm using devkitARM r19. i don't know if this just happens in my environment...
#101033 - HyperHacker - Fri Sep 01, 2006 9:06 pm
The only time I ever had malloc() return already-used pointers was when I was writing an array incorrectly and corrupting memory.
_________________
I'm a PSP hacker now, but I still <3 DS.
#101040 - Sausage Boy - Fri Sep 01, 2006 9:43 pm
Works fine for me on hardware, in dualis and in no$gba.
OS: Windows XP
gcc version: arm-eabi-gcc.exe (GCC) 4.1.1 (devkitARM
release 19b)
ld version: GNU ld version 2.17
build environment: MSYS
MSYS version: MINGW32_NT-5.1 KRANIUM 1.0.11(0.46/3/2) 2004-04-30 18:55 i686 unknown
Code: |
...
#include <stdio.h>
bool end=FALSE;
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
for (int i=0; i<9999; i++)
new int();
touchPosition touchXY;
videoSetMode(0); //not using the main screen
...
|
_________________
"no offense, but this is the gayest game ever"
#101075 - pkwong - Sat Sep 02, 2006 2:46 am
oops!
then it should be a weird problem happening to me only...