KINGx - Das inoffizielle PlayStation Forum & News Portal

Normale Version: malloc() freezed PSP
Sie sehen gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Heyho,

Ich programmiere momentan an einem kleinen Homebrew.
Ich habe mir eine Sprites Engine programmiert, die Sprites, etc. Für mich verwaltet, zeichnet, etc.

Allerdings habe ich ein Problem. In einer Funktion (Zum Laden von Grafiken) gibt es momentan Probleme.

Wenn ich die Datei "gfx/raumschiff.png" lade mit höhexbreite = 64x64 geht alles ohne Probleme.
Wenn ich jetzt aber die Datei "gfx/Hintergrund.png" lade mit höhexbreite = 480x272 stürzt das Programm bei dem malloc() für die Variable Images ab.

Hier die Funktion:

Code:
int loadSpriteImage(char* filename, int width, int height)
{
    // New Code:
    backUpImages = malloc(sizeof(struct SpriteImage) * imagesLoaded);
    int i;
    for(i = 0; i < imagesLoaded; i++)
    {
        backUpImages[i] = Images[i];
    }
    Images = malloc(sizeof(struct SpriteImage) * (imagesLoaded + 1)); // Hier hängt es
    Images[imagesLoaded].size.x = width;
    Images[imagesLoaded].size.y = height;
    Images[imagesLoaded].theImage = loadImage(filename);
    for(i = 0; i < imagesLoaded; i++)
    {
        Images[i] = backUpImages[i];
    }
    free(backUpImages);
    imagesLoaded++;
    return imagesLoaded+1;
}

Hier noch die Deklarationen der Variablen.

Code:
struct SpriteImage {
    struct Vector2 size;
    Image* theImage;
};
int imagesLoaded;
struct SpriteImage* Images;
struct SpriteImage* backUpImages;


Ich habe auch schon mit pspDebugScreenPrintf() versucht möglichst viele Infos zu sammeln. Alle Werte sind korrekt, aber wenn der filename = "gfx/Hintergrund.png" ist ist ende, dann freezed die PSP. Es werden beim ersten Aufruf genau 12Byte Allocated, beim zweiten 24, etc. habe ich alles schon getestet.

Hat jemand evtl. einen Tipp für mich?

Was beabsichtigst du mit diesem Code-Segment?
Ich denke, dass du in dem Array den Platz um ein Image erhöhen willst, liege ich da falsch?
Dann könntest du aber viel effizienter mit realloc() arbeiten und dir so einiges ersparen Wink .

mfg D3lta

P.S.: Warum gibst du ImageLoaded+2 zurück?
Ich gebe imagesLoaded+1 zurück, was totaler unsinn ist, wie mir eben aufgefallen ist ^^
Jetzt gebe ich imagesLoaded-1 zurück, was richtig ist (Steht für den Index im Array Images).

Ja, ich beabsichtige den Array um eins zu vergrößern.
realloc() wäre eine Möglichkeit, habe ich auch eben getestet.

Selbes Problem....
Ich habe mir erlaubt deinen Code etwas zu verändern:

Code:
int loadSpriteImage(char* filename, int width, int height)
{
    // New Code:
        int i;
    backUpImages = malloc(sizeof(struct SpriteImage) * imagesLoaded);
    for(i = 0; i &lt; imagesLoaded; ++i)
    {
        backUpImages[i] = Images[i];
    }
    Images = malloc(sizeof(struct SpriteImage) * (++imagesLoaded)); // Hier hängt es
    Images[imagesLoaded].size.x = width;
    Images[imagesLoaded].size.y = height;
    Images[imagesLoaded].theImage = loadImage(filename);
    for(i = 0; i &lt; imagesLoaded; ++i)
    {
        Images[i] = backUpImages[i];
    }
    free(backUpImages);
    return imagesLoaded;
}

Aber ist es so nicht viel einfacher?

Code:
int loadSpriteImage(char* filename, int width, int height)
{
    // new New Code ;) :
    Images = realloc(Images, sizeof(struct SpriteImage) * (++imagesLoaded)); // Hier hängt es
    Images[imagesLoaded].size.x = width;
    Images[imagesLoaded].size.y = height;
    Images[imagesLoaded].theImage = loadImage(filename);
    return imagesLoaded;
}


Sieht es so nicht gleich viel einfacher aus? Wink
Liegt der Fehler immer noch an der selben Stelle?

mfg D3lta

P.S.: Ich weiß schon, warum ich auf C++ umgestiegen bin ...

Achso, ich hatte realloc einfach anstatt von malloc() eingesetzt Big Grin

Aber wenn ich direkt beim realloc() imagesLoaded um 1 erhöhe kriege ich doch einen Buffer Overflow, oder?
Ich meine wenn 12 Bytes reserviert werden ist ja der höchst mögliche Index ohne Buffer Overflow 0, oder?

Dann dürfte imagesLoaded ja nicht inkrementell um eins erweitert werden sondern einfach nur +1 gerechnet werden oder?
und zurückgegeben muss dann nachdem imagesLoaded inkrementell um 1 erhöht wurde mit einem -1.
Also, ich habe mal deine Funktion ein wenig verändert und sie ausprobiert:

Code:
int loadSpriteImage(char* filename, int width, int height)
{
    // new New Code ;) :
    pspDebugScreenPrintf("Realloc() Images!\r\n");
    Images = realloc(Images, sizeof(struct SpriteImage) * (imagesLoaded+1)); // Hier hängt es
    pspDebugScreenPrintf("Realloc() Sucessfull oO!\r\n");
    Images[imagesLoaded].size.x = width;
    Images[imagesLoaded].size.y = height;
    Images[imagesLoaded].theImage = loadImage(filename);
    imagesLoaded++;
    return imagesLoaded-1;
}


Allerdings hängt er jetzt AUCH beim raumschiff.png.

Spongy :
Achso, ich hatte realloc einfach anstatt von malloc() eingesetzt Big Grin

Aber wenn ich direkt beim realloc() imagesLoaded um 1 erhöhe kriege ich doch einen Buffer Overflow, oder?
Ich meine wenn 12 Bytes reserviert werden ist ja der höchst mögliche Index ohne Buffer Overflow 0, oder?

Dann dürfte imagesLoaded ja nicht inkrementell um eins erweitert werden sondern einfach nur +1 gerechnet werden oder?
und zurückgegeben muss dann nachdem imagesLoaded inkrementell um 1 erhöht wurde mit einem -1.
Also, ich habe mal deine Funktion ein wenig verändert und sie ausprobiert:

Code:
int loadSpriteImage(char* filename, int width, int height)
{
    // new New Code ;) :
    pspDebugScreenPrintf("Realloc() Images!\r\n");
    Images = realloc(Images, sizeof(struct SpriteImage) * (imagesLoaded+1)); // Hier hängt es
    pspDebugScreenPrintf("Realloc() Sucessfull oO!\r\n");
    Images[imagesLoaded].size.x = width;
    Images[imagesLoaded].size.y = height;
    Images[imagesLoaded].theImage = loadImage(filename);
    imagesLoaded++;
    return imagesLoaded-1;
}


Allerdings hängt er jetzt AUCH beim raumschiff.png.


Stimmt Wink
Allerdings ist es so trotzdem für mich etwas schöner:

Code:
int loadSpriteImage(char* filename, int width, int height)
{
    // new New Code ;) :
    pspDebugScreenPrintf("Realloc() Images!\r\n");
    Images = realloc(Images, sizeof(struct SpriteImage) * (++imagesLoaded)); // Hier hängt es
    pspDebugScreenPrintf("Realloc() Sucessfull oO!\r\n");
    Images[imagesLoaded-1].size.x = width;
    Images[imagesLoaded-1].size.y = height;
    Images[imagesLoaded-1].theImage = loadImage(filename);
    return imagesLoaded;
}

Hast du einmal versucht, andere Bilder zu laden, oder alle außer raumschiff.png?
Wieviele Dateien lädt die Funktion denn erfolgreich?

mfg D3lta

P.S.: Warum inkrementierst du den Wert immer um 1 und gibst ihn dann um 1 dekrementiert zurück?

Ich inkrementiere um eins, weil wenn der Index 0 vorhanden ist ein Bild geladen ist.
Also ist imagesLoaded - 1 immer der letzt mögliche Index im Images Array.

Die Funktion hat vorher raumschiff.png immer ohne Probleme geladen, nur Hintergrund.png konnte nicht geladen werden. Die PSP Freezed immer, und mit deiner Funktion kann ich auch raumschiff.png nicht laden.

Ich werde nachher mal versuchen andere Bilder zu laden.
Wenn ich dich richtig verstanden habe, gibst du bei deiner Funktion immer den höchstmöglichen Index zurück, oder?
Es ist aber üblich die Größe zurückzugeben, was ich in meinen Funktionen auch gemacht habe. Wink
Dadurch kommt, wenn du den maximalen Index erwartest, ein Overflow zustande.

mfg D3lta
Ich erwarte ja nicht den maximalen Index Wink
Es wird ja von der Funktion zurückgegeben, an welcher Position sich das Bild im Array befindet.
Und genau das bekomme ich beim Laden eines Sprites wieder "mitgeliefert".

Dann wird in einem Sprite Array etwa das gleiche wie bei dem Images Array gemacht (Da funktionierts) und der Sprite gespeichert.

Ich habe auch mal noch andere Bilder ausprobiert. Mit meiner Funktion funktioniert es, die raumschiff.png zu laden, andere Bilder können damit nicht geladen werden.
Mit deiner Funktion stürzt er auch schon beim laden des Raumschiffs ab, wobei ich da einfach keinen Grund sehe.

Warum sollte die PSP beim reservieren von 12 Byte Ram abstürzen? :S

Spongy :
Ich erwarte ja nicht den maximalen Index Wink
Es wird ja von der Funktion zurückgegeben, an welcher Position sich das Bild im Array befindet.
Und genau das bekomme ich beim Laden eines Sprites wieder "mitgeliefert".

Dann wird in einem Sprite Array etwa das gleiche wie bei dem Images Array gemacht (Da funktionierts) und der Sprite gespeichert.

Ich habe auch mal noch andere Bilder ausprobiert. Mit meiner Funktion funktioniert es, die raumschiff.png zu laden, andere Bilder können damit nicht geladen werden.
Mit deiner Funktion stürzt er auch schon beim laden des Raumschiffs ab, wobei ich da einfach keinen Grund sehe.

Warum sollte die PSP beim reservieren von 12 Byte Ram abstürzen? :S


Ungünstige Speicherauslastung seitens FW? Wink
Mir fällt momentan auch nichts ein, außer ungünstige Zeiger.
Sind die Zeiger global deklariert?
Sind sie mit NULL initialisiert?

mfg D3lta

Ich habe eben die Funktion calloc() "gefunden".
Ich habe sie mal testweise eingebaut und siehe da, alles hat funktioniert.

Ich frage mich nur noch, warum es jetzt damit geht und nicht mit malloc :S
calloc() initialisert den reservierten Speicher mit Nullen, aber sonst ist da kein Unterschied Noidea

D3lta :
Sind die Zeiger global deklariert?
Sind sie mit NULL initialisiert?


mfg D3lta

Die Zeiger sind in einer Headerdatei deklariert.
Initialisiert werden sie überhaupt nicht. Das erste mal wenn ein Sprite oder ein Image geladen wird.

Spongy :
Die Zeiger sind in einer Headerdatei deklariert.
Initialisiert werden sie überhaupt nicht. Das erste mal wenn ein Sprite oder ein Image geladen wird.


Das könnte ein Fehler sein, initialisiere sie in der main() einmal mit NULL und führe dann einmal meine Routine aus.

mfg D3lta

Referenz-URLs