Merkwürdiges Verhalten von calloc in Verbindung mit scrnsaver.lib
-
Moin, moin,
habe hier einen Screensaver der korrekt startet und durchläuft, wenn ich diesen via Kommandozeile starte:
screensafer.scr /soder
screensafer.scr /cAllerdings, und jetzt kommt es, in der Vorschau und wenn Windows den Screensafer starten möchte *patsch* "screensafer.scr hat ein Problem festgestellt und ..."
Ich konnte den Fehler auf folgende Codezeile eingrenzen:
st->lenses = (Lens *)calloc(st->lensnum, sizeof(Lens));Ich schlage mich jetzt schon ein bis zwei Wochen (allerdings hobbymäßig) mit diesem Problem rum und versteh nicht wieso es läuft, wenn ich es von der Konsole starte und nicht in der Miniaturvorschau der Bildschirmschoner-Eigenschaften?
Anbei noch das typedef für Lens:
typedef struct Lens { double r, // Rotation s, // Scale tx, // Translation ty; // Translation double ro, // Rotation zuvor rt, // Rotationsziel rc; // Rotationszähler double so, // Skalierung zuvor st, // Skalierungsziel sc; // Skalierungszähler double sa, // Skalierung Wichtung txa, // Translation Wichtung tya; // Translation Wichtung int ua, // berechnete r,s,t ub, utx; int uc, // berechnete r,s,t ud, uty; } Lens;Und in der Structur "st" (die, um hier komplett zu posten, viel zu lang ist) sind die benutzten Elemente wie folgt definiert:
int lensnum; // Anzahl der Linsen Lens *lenses; // Zeiger auf LinsenGrübel, grübel ...
-
der fehler liegt an einer anderen stelle.
-
Ist 'lenses' korrekt initialisiert (lies: Zeigt diese Variable auf einen gültigen Speicherbereich ?) ? Du musst ggf. mit new/malloc allokieren, oder gleich auf die Zeigerarithmetik verzichten (auf jeden Fall sinnvoller, verstehe sowieso nicht warum das immer so viele machen
).
-
CodeFinder schrieb:
Ist 'lenses' korrekt initialisiert (lies: Zeigt diese Variable auf einen gültigen Speicherbereich ?) ? Du musst ggf. mit new/malloc allokieren, oder gleich auf die Zeigerarithmetik verzichten (auf jeden Fall sinnvoller, verstehe sowieso nicht warum das immer so viele machen
).Ähem, wie jetzt! Allokiere ich mit calloc nicht einen Speicherbereich und initialisieren den Zeiger st->lenses mit der Startadresse des Speicherbereichs?
Ein Umschreiben der betroffenen Codeabschnitte kommt zur Zeit nicht in Frage, ich bin blutiger Anfänger und würde Wochen dafür brauchen.

@callo:
Ein Systembeep vor dem genannten Ausschnitt wird ausgeführt, ein Systembeep in der Zeile danach nicht. Der Fehler muss meinem Verständnis nach mit dieser Codezeile zusammenhängen. Lasse mich aber gern eines besseren belehren.Edit: Typos
-
Debugger.
-
Ne ich mein das anders:
Wenn st eine Zeigervariable ist, dann muss die vorher auch initialisiert sein, damit du auf das Element lenses von st zugreifen kannst. Anderfalls erzeugst Du hier schon die Speicherzugriffsverletzung.
st muss also auf einen gültigen Speicherbereich zeigen
.
Zeig mir mal die Definition bzw. vorherige Benutzung (->Initialisierung) - falls vorhanden
- von st.
-
CodeFinder schrieb:
Zeig mir mal die Definition bzw. vorherige Benutzung (->Initialisierung) - falls vorhanden
- von st.Anmerkung: gebe ich st->lenses und sizof(st->Lens) aus erhalte ich die Werte 3 und 128 was korrekt ist).
Here we go, die komplette Funktion die mir die Struktur erstellt.///////////////////////////////////// // Initialisiere IFS-Struktur static state * ifs_init (void) { struct state *st = (struct state *) calloc (1, sizeof(*st)); ifs_reshape(st, myScreenSize.right, myScreenSize.bottom); if (NCLR % 2 == 0) // Anzahl der Farben muss ungerade sein! st->ncolours = NCLR + 1; else st->ncolours = NCLR; // TODO: lese/schreibe Einstellungen st->length = 10; // TODO: lese/schreibe Einstellungen st->rotate = true; // TODO: lese/schreibe Einstellungen st->scale = true; // TODO: lese/schreibe Einstellungen st->translate = true; // TODO: lese/schreibe Einstellungen st->recurse = true; // TODO: lese/schreibe Einstellungen st->lensnum = 3; // TODO: lese/schreibe Einstellungen st->colorfreq = CLRFREQUENCY; // TODO: lese/schreibe Einstellungen // Größe einer Bildschirmzeile in Bytes st->scanline = (bmih.biWidth * (bmih.biBitCount / 8)) >> 2; // Standardfarben st->hbrBlack = (HBRUSH)GetStockObject(BLACK_BRUSH); st->hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH); // Erstelle Polarkoordinaten als Cashe (array) zum Zeichnen radialer Farbverläufe (0,0 ist die Mitte des Bildschirms) if (st->xpolar) free(st->xpolar); st->xpolar = (int *)calloc(myScreenSize.right, sizeof(int)); for (int i = 0; i <= myScreenSize.right;i++){ st->xpolar[i] = -(myScreenSize.right/2) + i; } if (st->ypolar) free(st->ypolar); st->ypolar = (int *)calloc(myScreenSize.bottom, sizeof(int)); for (int i = 0; i <= myScreenSize.bottom;i++){ st->ypolar[i] = -(myScreenSize.bottom/2) + i; } // Hole Speicher für Farbtabelle (Hinweis: BBGGRR00 ist ein typedef vom Typ COLORREF wird nur rückwärts verwendet) if (st->colours) free(st->colours); st->colours = (BBGGRR00 *)calloc(st->ncolours, sizeof(BBGGRR00)); if (!st->colours) exit(1); if (st->lenses) free (st->lenses); // CRASH ////////////////////////////////////////////// st->lenses = (Lens *)calloc(st->lensnum, sizeof(Lens)); /////////////////////////////////////////////////////// if (!st->lenses) exit(1); for (int i = 0; i < st->lensnum; i++) { CreateLens(st, (myrandom(1.0) - 0.5), myrandom(1.0), myrandom(4.0) - 2.0, myrandom(4.0) + 2.0, &st->lenses[i]); } return st; }
-
Erstmal ist die st doch frisch erzeugt. Da dürften die Abfragen
if(st->...) free(st->...);unnötig sein. (btw, was genau macht ifs_reshape() mit dem Parameter?)Danach solltest du dir mal den Debugger vornehmen und das Programm Schritt für Schritt durchlaufen lassen.