Wie funktioniert memset?
-
Hallo ich habe mich eben ein bisschen mit der Funktion memset() beschäftig und habe einige Probleme damit.
Ich fand folgendes im Internet:void *memset(void *adres, int zeichen, size_t n);
Mit der Funktion memset() wird der Wert von zeichen in jedes der ersten n Zeichen des Speicherbereichs mit der Adresse adres geschrieben. Das sieht dann wie folgt aus:
int bigarray[1000];
memset(bigarray, 0, sizeof(bigarray));Nur ich verstehe diesen Text leider nicht so wirklich.
Ich dachte zuerst die Funktion sei da um alle Werte eines Array's mit dem gleichen Wert zu versehen aber als ich die Funktion in einem Test ausprobierte sah ich das ich mich irrte.
Könnte mir jemand die Funktion memset() mit seinen eigenen Worten erklären?EDIT:\\ Hier mein Test Code:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int test[15]; test[0] = 1; test[1] = 2; test[2] = 3; test[3] = 4; test[4] = 5; printf ("Array Test 0 = %d\n",test[0]); printf ("Array Test 1 = %d\n",test[1]); printf ("Array Test 2 = %d\n",test[2]); printf ("Array Test 3 = %d\n",test[3]); printf ("Array Test 4 = %d\n",test[4]); memset (test,1,sizeof(test)); //Setze alle anderen Werte auf 1 printf ("Array Test 0 = %d\n",test[0]); printf ("Array Test 1 = %d\n",test[1]); printf ("Array Test 2 = %d\n",test[2]); printf ("Array Test 3 = %d\n",test[3]); printf ("Array Test 4 = %d\n",test[4]); system("PAUSE"); return 0; }
-
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char test[15]; test[0] = 1; test[1] = 2; test[2] = 3; test[3] = 4; test[4] = 5; printf ("Array Test 0 = %d\n",test[0]); printf ("Array Test 1 = %d\n",test[1]); printf ("Array Test 2 = %d\n",test[2]); printf ("Array Test 3 = %d\n",test[3]); printf ("Array Test 4 = %d\n",test[4]); memset (test,1,sizeof(test)); //Setze alle anderen Werte auf 1 printf ("Array Test 0 = %d\n",test[0]); printf ("Array Test 1 = %d\n",test[1]); printf ("Array Test 2 = %d\n",test[2]); printf ("Array Test 3 = %d\n",test[3]); printf ("Array Test 4 = %d\n",test[4]); system("PAUSE"); return 0; } :clown:
-
memset arbeitet auf Bytes. Da ein "int" aber i.d.R. aus ein paar Bytes besteht, werden alle Bytes des 'int's auf den Wert (hier 1) gesetzt.
Die binärdarstellung der 1 in einem 4-bytigen int wäre aber 0x00000001 und nicht 0x01010101.
-
Hi !
Auch wenn der zweite Parameter von memset ein int ist,
memset schreibt byte für byte ne 1 in den puffer.
memset (test,1,4) sieht dann so aus:
00000001000000010000000100000001Ein int hat 4 Byte, die obige Binärzahl ist dezimal 16843009
Darum kommen bei der Ausgabe lauter 16843009 zur Anzeige.
-
BauerSuchtFrau schrieb:
memset (test,1,sizeof(test));
richtig gehts so:
[cpp]
memset (**&**test,1,sizeof(test));
[/cpp][/quote]
-
memset schrieb:
richtig gehts so:
[cpp]
memset (**&**test,1,sizeof(test));
[/cpp]stimmt.
ohne & ist es auch richtig.
-
streng genommen müsste man
memset ( (void*)test, 1, sizeof(test) );
schreiben, weil memset nen zeiger auf void als ersten parameter will.
test ist ein int*, &test ist ein int**.
das es auch mit &test funktioniert liegt wohl daran, das keine zweite adresse für &test spendiert werden kann, darum ist die adresse &test gleich der adresse test.
-
Big Brother schrieb:
streng genommen müsste man
memset ( (void*)test, 1, sizeof(test) );
schreiben, weil memset nen zeiger auf void als ersten parameter will.
test ist ein int*, &test ist ein int**.
das es auch mit &test funktioniert liegt wohl daran, das keine zweite adresse für &test spendiert werden kann, darum ist die adresse &test gleich der adresse test.Unfug (der Code würde funktionieren, den Rest kann man vergessen).
-
Big Brother schrieb:
streng genommen müsste man
memset ( (void*)test, 1, sizeof(test) );
schreiben, weil memset nen zeiger auf void als ersten parameter will.
Mumpitz.
Big Brother schrieb:
test ist ein int*, &test ist ein int**.
Zweimal falsch. test ist ein int-Array, &test ein Zeiger auf ein int-Array. Ersteres zerfällt bei der erstbesten Gelegenheit in einen Zeiger auf das erste Element (int*), letzteres hat dieselbe Adresse, nur einen anderen Typ.
-
Big Brother schrieb:
Auch wenn der zweite Parameter von memset ein int ist,
memset schreibt byte für byte ne 1 in den puffer.
memset (test,1,4) sieht dann so aus:
00000001000000010000000100000001huch? wo kommen denn immer diese 7 nullen dazwischen her?
oder soll das der inhalt des arrays in binärdarstellung sein?
-
camper schrieb:
Unfug (der Code würde funktionieren, den Rest kann man vergessen).
MFK schrieb:
Mumpitz. ....
Zweimal falsch.Quatsch mit Sauße.
Annähernd vergessen kann man das hier:
&test ist ein int**
Richtig ist:
&test ist ein int(*)[15]Deklaration von memset:
void *memset( void *dest, int c, size_t count );dest sieht mir stark nach einem void Zeiger aus.^^
array, ptr, sind Zeiger auf int:
int test[15]; // Integer Array int* ptr = array; memset( test, 1, sizeof(test) ); memset ( ptr, 1, sizeof(test) );
Wie mache ich aus einem Zeiger auf int ( int* ) einen Zeiger auf void ( void* )
Simsalabim,
int Zeiger nach void* casten:memset( (void*)test, 1, sizeof(test) ); memset ( (void*)ptr, 1, sizeof(test) );
Wenn das Mumpitz und Unfug sein soll Jungs, verratet mir doch mal, wieso mein Compiler auf der höchsten Warnstufe keinen Mucks von sich gibt ?
holyzero-freak schrieb:
huch? wo kommen denn immer diese 7 nullen dazwischen her?
oder soll das der inhalt des arrays in binärdarstellung sein?
Big Brother schrieb:
...die obige Binärzahl ist dezimal 16843009 ...
Ja.
-
Big Brother schrieb:
Wie mache ich aus einem Zeiger auf int ( int* ) einen Zeiger auf void ( void* )
Simsalabim,
int Zeiger nach void* casten:Oder einfach gar nichts tun, weil jeder Zeiger implizit in void* konvertierbar ist. Du baust einen Zaubertrick um etwas, das von ganz allein passiert.
Big Brother schrieb:
Wenn das Mumpitz und Unfug sein soll Jungs, verratet mir doch mal, wieso mein Compiler auf der höchsten Warnstufe keinen Mucks von sich gibt ?
Mumpitz ist deine Behauptung, dass man das "strenggenommen" nach void* casten müsste.
Was sagt denn dein Compiler, wenn du den Cast weglässt?
-
MFK schrieb:
Oder einfach gar nichts tun, weil jeder Zeiger implizit in void* konvertierbar ist. Du baust einen Zaubertrick um etwas, das von ganz allein passiert.
Der Zaubertrick ist ein gewöhnliches Sprachmittel von C, ein Cast. Das die Umwandlung automatisch geschieht, wird wohl so sein, letztlich ist ja nur die Adresse von Bedeutung.
MFK schrieb:
Was sagt denn dein Compiler, wenn du den Cast weglässt?
Der sagt mir alles ok. Den interessiert nicht, ob ich nen Zeiger auf int übergebe, oder ob ich den Zeiger gemäß memset - Deklaration nach void caste.
Wenn ich Zeit übrig habe, gucke ich mal nach, ob der Draft etwas dazu sagt.
-
sorry, wenn ich mich als newbie hier einmische, aber für mich macht "memset" nur bei Zeichenketten oder zum "Ausnullen" Sinn.
char sz[] = "Hallo Welt"; int test[10]; memset(sz, 'a', strlen(sz)); memset(test,0,sizeof(test));
Wenn ich ein int - Array mit "sinnvollen" Werten füllen will, bleibt meines Erachtens nur, Wert für Wert zu setzen.
Oder?
-
Big Brother schrieb:
MFK schrieb:
Oder einfach gar nichts tun, weil jeder Zeiger implizit in void* konvertierbar ist. Du baust einen Zaubertrick um etwas, das von ganz allein passiert.
Der Zaubertrick ist ein gewöhnliches Sprachmittel von C, ein Cast. Das die Umwandlung automatisch geschieht, wird wohl so sein, letztlich ist ja nur die Adresse von Bedeutung.
MFK schrieb:
Was sagt denn dein Compiler, wenn du den Cast weglässt?
Der sagt mir alles ok. Den interessiert nicht, ob ich nen Zeiger auf int übergebe, oder ob ich den Zeiger gemäß memset - Deklaration nach void caste.
Wenn ich Zeit übrig habe, gucke ich mal nach, ob der Draft etwas dazu sagt.Naja, man kann des Cast schon machen, aber er ist absolut überflüssig und in der Regel nicht zu empfehlen. Der einzige Fall, wo es Sinn macht, ist wenn man C-Code in einem C++ Projekt übersetzen will. C++ fordert nämlich den Cast.
-
kzH schrieb:
sorry, wenn ich mich als newbie hier einmische, aber für mich macht "memset" nur bei Zeichenketten oder zum "Ausnullen" Sinn.
char sz[] = "Hallo Welt"; int test[10]; memset(sz, 'a', strlen(sz)); memset(test,0,sizeof(test));
Wenn ich ein int - Array mit "sinnvollen" Werten füllen will, bleibt meines Erachtens nur, Wert für Wert zu setzen.
ganz richtig^^
ints sind meistens grösser als chars und weil memset den speicher als eine folge von 'unsigned chars' betrachtet, haut das voll nicht hin.
-
kzH schrieb:
sorry, wenn ich mich als newbie hier einmische, aber für mich macht "memset" nur bei Zeichenketten oder zum "Ausnullen" Sinn.
char sz[] = "Hallo Welt"; int test[10]; memset(sz, 'a', strlen(sz)); memset(test,0,sizeof(test));
Dies ist kein Forum für Fortgeschrittene.
kzH schrieb:
Wenn ich ein int - Array mit "sinnvollen" Werten füllen will, bleibt meines Erachtens nur, Wert für Wert zu setzen.
Oder?Ja, genau. Alles andere ist Frickelunsinn.
-
Der Cast ist bloß überflüssig, auch in C++. Das genügt nicht, um das Ganze als Unfug zu qualifizieren. Allerdings fällt es schwer, mit der Ignoranz umzugehen, die Arrays und Zeiger durcheinander würfelt und gleichzeitig noch auf dem Umgang mit dem exakten Zeigertyp besteht.
Arrays sind keine Zeiger. Arrays sind keine Zeiger. Arrays sind keine Zeiger.
Ein Array kann überall benutzt werden, wo ein Zeiger erwartet. Ebenso wie z.B. ein int benutzt werden kann, wo ein double erwarte wird. Das bedeutet aber natürlich nicht, dass int und double identisch wären. Ein Objekt oder Ausdruck hat stets einen eindeutig bestimmten Typen, da Zeiger und Arrays verschiedene Typen sind, kann weder ein Objekt noch ein Ausdruck gleichzeitig Array und Zeiger sein. Es wäre wirklich schön, wenn solche Diskussionen gelegentlich auf erworbenem Wissen und nicht nur auf Hörensagen und Vermutungen beruhen würden - ebenso wie etwa die völlig überflüssige Bemerkung bzgl. Casts in C++ (was wirklich nicht so kompliziert ist, dass man sich nicht zuerst darüber sicheres Wissen aneignen könnte). Komischerweise sind es nämlich immer gerade diese, die von Anfängern aufgeschnappt werden - und man verschwendet dann Zeit, diesen Eindruck erst einmal korrigieren zu müssen.
-
Tachyon schrieb:
Der einzige Fall, wo es Sinn macht, ist wenn man C-Code in einem C++ Projekt übersetzen will. C++ fordert nämlich den Cast.
besser: dann compiliert man den c-code trotzdem mit 'nem c-compiler und der linker erledigt den rest.
-
ansiC bad ass schrieb:
Tachyon schrieb:
Der einzige Fall, wo es Sinn macht, ist wenn man C-Code in einem C++ Projekt übersetzen will. C++ fordert nämlich den Cast.
besser: dann compiliert man den c-code trotzdem mit 'nem c-compiler und der linker erledigt den rest.
Genau für diesen Fall gibt es überhaupt keine Kompatibilitätsprobleme zwischen C und C++. Ein C Compiler ist also hier nicht von nöten.