Absturz bei Aufruf der Funktion memset

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
HeReSY
Beiträge: 12
Registriert: 06.06.2002, 22:33
Wohnort: Sprockhövel

Absturz bei Aufruf der Funktion memset

Beitrag von HeReSY »

Hallo,

in meinem Programm nutze ich memset um den Inhalt eines array's auf Null zu setzten

Code: Alles auswählen

unsinged char key[16];
...
memset(key, 0x00, sizeof(key));
So, jetzt bekomme ich irgendwann einmal in meinem Programm einen Segfault, der auf diese Stelle verweist.
Da stellt sich mir natürlich die Frage, was kann bei einem memset alles so falsch laufen?

Habe anschließend mal gegoogelt und eine ungereimtheit gefunden.
Einige rufen memset so auf, wie es bei mir der Fall ist, andere wiederum rufen es wie folgt auf.

Code: Alles auswählen

memset(&key, 0x00, sizeof(key));
Welches der beiden Fälle ist denn nun richtig? Bisher ist für mich immer der obige Fall richtig gewesen, da er ja ein painter auf das erste element des Array's ist.
Im zweiten Fall, erhalte ich meiner Meinung nach aber den Pointer des Pointers, oder etwa nicht?

HeReSY
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Absturz bei Aufruf der Funktion memset

Beitrag von Schrompf »

Doch, da hast Du Recht. Manche Leute schreiben ein &(bla[0]), also die Adresse des ersten Elements. Das ist aber nur syntaktischer Bonus, der zumindest für schlichte C-Arrays weggelassen werden kann.

Der Absturz liegt dann wohl an was anderem. Setze mal einen Breakpoint drauf und schau, wie zu dem Zeitpunkt "key" aussieht. Evtl. hast Du lokal eine andere Variable mit Namen "key" definiert, weswegen das globalere Array dann ausgeblendet wird.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Absturz bei Aufruf der Funktion memset

Beitrag von BeRsErKeR »

HeReSY hat geschrieben:

Code: Alles auswählen

memset(&key, 0x00, sizeof(key));
Welches der beiden Fälle ist denn nun richtig? Bisher ist für mich immer der obige Fall richtig gewesen, da er ja ein painter auf das erste element des Array's ist.
Im zweiten Fall, erhalte ich meiner Meinung nach aber den Pointer des Pointers, oder etwa nicht?
Korrekt. Die zweite Variante ist nicht der richtige Weg. So einen memset Aufruf (mit dem &) nutzt man in der Regel für normale Instanzen:

Code: Alles auswählen

struct foo
{
int x;
float y;
};

...

foo f;
memset(&f, 0, sizeof(f));
Oder man nimmt die Variante von Schrompf, aber das macht in meinen Augen eher dann Sinn, wenn man nur einen bestimmten Teil setzen will.

Mit dem sizeof am Ende solltest du übrigens vorsichtig sein. Bei dynamischen Arrays kannst du das so nicht machen, das klappt nur bei statischen Arrays.
Ohne Input kein Output.
HeReSY
Beiträge: 12
Registriert: 06.06.2002, 22:33
Wohnort: Sprockhövel

Re: Absturz bei Aufruf der Funktion memset

Beitrag von HeReSY »

Danke für die Antworten,

da das Array eine feste Größe hat, kann ich das an der Stelle auch ruhigen Gewissens so machen.
Das was mich noch ein wenig verwirrt ist, dass beide memset aufrufe, so wie ich sie beschrieben habe auch funktionieren.
Eigentlich müsste doch beim zweiten memset(&key...) der Compiler ne Fehlermeldung oder mindestens eine Warnung ausgeben, das tut er allerdings nicht.

Habe mir dann dazu auch mal den Assembler-Code angeschaut, den der Compiler erzeugt. Es wird an diesen Stellen überhaupt kein memset aufgerufen, also kann der Fehler letztendlich nicht am memset liegen. Der Compiler beschreibt einfach nur jeweils 32bit pointer mit 0.
Habe das ganze dann auch mal mit einer for-Schleife getestet. Hierbei nutzt der Compiler dann auch memset. Allerdings funktioniert dann mein Programm nicht mehr richtig. wieseo weshalb auch immer.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Absturz bei Aufruf der Funktion memset

Beitrag von Krishty »

HeReSY hat geschrieben:Eigentlich müsste doch beim zweiten memset(&key...) der Compiler ne Fehlermeldung oder mindestens eine Warnung ausgeben, das tut er allerdings nicht.
U.a. deshalb ist memset() ja auch so gefährlich.
HeReSY hat geschrieben:Habe mir dann dazu auch mal den Assembler-Code angeschaut, den der Compiler erzeugt. Es wird an diesen Stellen überhaupt kein memset aufgerufen, also kann der Fehler letztendlich nicht am memset liegen. Der Compiler beschreibt einfach nur jeweils 32bit pointer mit 0.
memset() ist als Intrinsic Function bekannt, der Compiler kennt also ihr Verhalten und es steht ihm frei, gleichwertigen optimierten Text zu erzeugen statt die Funktion aufzurufen.
HeReSY hat geschrieben:Allerdings funktioniert dann mein Programm nicht mehr richtig. wieseo weshalb auch immer.
Wahrscheinlich aus dem selben Grund, aus dem auch der Segmentation Fault kommt: Irgendwo irgendwas kaputtgemacht. Falls du VCpp benutzt: /GS aktiviert, mal mit dem AppVerifier ausgeführt?

Die beste Methode, das Array zu Null zu intialisieren, ist übrigens immernoch unsinged char key[16] = { 0x00 }; ;)

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
HeReSY
Beiträge: 12
Registriert: 06.06.2002, 22:33
Wohnort: Sprockhövel

Re: Absturz bei Aufruf der Funktion memset

Beitrag von HeReSY »

Benutze nur den Compiler von Microsift. Als IDE den Qt-Creator.

Ich würde mein key gerne so initialisieren, allerdings ist das ne member von meiner Klasse, und da geht das leider nicht so.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Absturz bei Aufruf der Funktion memset

Beitrag von Krishty »

Das geht in der Initialisierungsliste des K’tors, indem du key() schreibst (Default Initialization bedeutet bei POD Arrays immer Zero Initialization). VC schmeißt dann eine Warnung (weil das Verhalten erst vor einigen Jahren hinzugefügt wurde), aber die kannst du ignorieren / abschalten.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Absturz bei Aufruf der Funktion memset

Beitrag von BeRsErKeR »

HeReSY hat geschrieben:Eigentlich müsste doch beim zweiten memset(&key...) der Compiler ne Fehlermeldung oder mindestens eine Warnung ausgeben, das tut er allerdings nicht.
Der Compiler meckert nicht, weil der erste Parameter ein void-Pointer ist. Und ein Pointer auf einen Pointer ist immer noch ein Pointer.
Ohne Input kein Output.
Antworten