Gefahren durch Pointer ?



  • kann es sein, dass ich mir mit pointern einen Teil in meinem Betriebssystem (win2k pro) überschrieben habe ?? Mein Debugger versucht nämlich andauernd mein System an stellen zu reparieren ??? Kann sowas vorkommen ?

    [ Dieser Beitrag wurde am 19.05.2003 um 16:54 Uhr von andro editiert. ]



  • Du kannst dir höchstens Betriebssystemteile im RAM überschreiben. z.B.

    int* a;
    a[2] = 324; //!!!!! a zeigt noch irgendwohin im Speicher!
    
    //so ists besser:
    
    int* a;
    a = (int*)malloc(4 * sizeof(int));
    a[2] = 324; //jetzt gehts
    

    also Pointer immer initialisieren!



  • bei modernen OSs kann man idr. den Kernel oder andere Software nicht überschreiben!

    also Pointer immer initialisieren!

    das hilft aber nicht dagegen über Speichergrenzen zu schreiben

    int *a=NULL;
    a[2]=1; //ups :)
    

    oder

    int b[2];
    int *a=&b;
    a[100]=1; //ups :)
    

    und man sollte den Rückgabewert von malloc nicht casten!



  • aha, dann bin ich ja beruhigt 🙂



  • Original erstellt von kingruedi:
    und man sollte den Rückgabewert von malloc nicht casten!

    Ohne nimmt er es bei mir aber nicht!



  • Dann hast du entweder stdlib.h nicht eingebunden, oder programmierst nicht C.



  • Original erstellt von <access violation>:
    Ohne nimmt er es bei mir aber nicht!

    Dann hast du bestimmt einen C++-Compiler. Schonmal was von new gehört???



  • Original erstellt von kingruedi:
    und man sollte den Rückgabewert von malloc nicht casten!

    Wieso nicht? Natürlich wird implizit von "void *" auf den entsprechenden Datentyp gecastet, aber mit einer expliziten Angabe unterstreicht man doch, was man mit malloc() vorhatte?! Das erhöht die Lesbarkeit, wieso sollte man das also nicht tun?

    😕



  • int speed = 20; //eine neue variable namens 'speed' vom typ int, die die geschwindigkeit des shuttles angibt, mit 10 initialisieren.
    
    int result = speed * 14; //rechne mal 15 und speichere das ergebnis in 'result'
    


  • @RTC:

    int main(void)
    {
      char* p=(char*)malloc(100);
      free(p);
      return 0;
    }
    

    das erzeugt undefiniertes verhalten in < C99



  • Ich finde deine Antwort absolut unzureichend.
    Versuch das doch mal bitte mit den Ursachen zu erklären und nicht mit den Folgen.
    also was geht da genau ab ??? Besser gefragt: Wieso kommt es zu undefiniertem Verhalten wenn man pointer castet?



  • comp.lang.c

    Standard C does not require a cast for assignments from a (void 😉 type to
    some other pointer type. The "narrowing" is done for you. Since malloc()
    returns a `void *', no cast is required.

    As has been repeated here before, an explicit cast is discouraged,
    because if there is not a prototype in scope, malloc() is assumed to be
    a function returning an int'. Without a prototype in scope, the cast will hide the fact that malloc() has returned anint' rather than a
    void *', and your compiler will not have had the opportunity to warn you about the mistake. If the size of anint' is not the same size as
    a `void *' on your machine, then `bad things will happen'. If it does
    happen to work on your machine, then you will become terribly confused
    when the identical code does not work on someone else's machine.
    .
    .
    .
    If you get a warning about there being no prototype for malloc() in
    scope then your code is broken, pure and simple. No amount of casting
    will cure it.

    This is the reason for advising against casting the result of malloc().
    If you cast the result of malloc then *some* compilers will still detect
    the error of not including stdlib.h. If you don't cast the result
    of malloc then *all* compilers will detect it.



  • "Na bitte, geht doch!"

    Ich denk mal die meisten Leute casten aus dem selben Grund wie ich, nämlich weil der Compiler ne warnung rausgibt das man einen INT einem Pointer zuweist. Und wenn man nun Warnings als Errors behandeln lässt, kompiliert das Programm erst gar nicht. Aus diesem Grund sehe ich Casten in der Praxis als teilweise gerechtfertigt.



  • Original erstellt von <jetztweisichs>:
    Ich denk mal die meisten Leute casten aus dem selben Grund wie ich, nämlich weil der Compiler ne warnung rausgibt das man einen INT einem Pointer zuweist. Und wenn man nun Warnings als Errors behandeln lässt, kompiliert das Programm erst gar nicht. Aus diesem Grund sehe ich Casten in der Praxis als teilweise gerechtfertigt.

    *PLONG*
    binde einfach <stdlib.h> ein!
    Ohne Prototypen zu arbeiten ist eh zu unsicher!



  • versteh ich ehrlich gesagt immer noch nicht.
    wenn ich einen Pointer vom Typ void auf einen Pointer eines anderen Typs caste, dann kann doch eigentlich nichts schief gehen, da die Pointer (egal welchen Typs) doch immer die gleiche Größe an Speicher nutzen.



  • Original erstellt von Ingo aka Desert Hawk:
    versteh ich ehrlich gesagt immer noch nicht.
    wenn ich einen Pointer vom Typ void auf einen Pointer eines anderen Typs caste,

    void* auf irgendwas* zu casten ist ungefährlich. Sogar SO ungefährlich, dass die Sprache das von alleine kann. Gefährlich ist ein Cast von int auf irgendwas*, und genau den hast Du, wenn Du vergisst, stdlib.h zu importieren. Und wenn Du Pech hast, kriegst Du dann mit Cast nichtmal mehr 'ne Warnung.



  • Hallo zusammen,

    jetzt hab ich mir das doch alles mal reingezogen und hab da eine Frage:

    Wenn das so ist, wie oben gesagt wurde, warum erhalte ich dann unter Visual C++ 6.0 den folgenden Fehler bei unten stehendem Code:

    error C2440:
    '=' : 'void *' kann nicht in 'int ' konvertiert werden Konvertierung von 'void' in Zeiger auf nicht-'void' erfordert eine explizite Typumwandlung

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char* argv[])
    {
    int* p;

    p = malloc(1024);

    return 0;
    }

    Sieht der Code allerdings so aus, gibs keine probleme:

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char* argv[])
    {
    int* p;

    p = (int*) malloc(1024);

    return 0;
    }

    Wie ihr seht, ist die stdlib.h aber drin.

    Hat darauf jemand eine Antwort ? Bin für jede Hilfe dankbar.



  • Ach so,

    sorry, hab ich vergessen. da gehört natürlich noch ein free(p) rein.

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char* argv[])
    {
    int* p;

    p = malloc(1024);

    free(p);

    return 0;
    }



  • Weil du wahrscheinlich einen C++ Compiler benutzt. Wenn du den VC++ dazu überreden kannst, im C-Modus zu compilieren, wird es wahrscheinlich funktionieren.



  • Original erstellt von Bashar:
    Weil du wahrscheinlich einen C++ Compiler benutzt. Wenn du den VC++ dazu überreden kannst, im C-Modus zu compilieren, wird es wahrscheinlich funktionieren.

    Ok. Und was muss ich dann machen unter einem c++ compiler, damit ich malloc verwenden kann. weil, wenn ich das richtig verstanden habe, dann ist das casten nicht so heiss. aber anderseits will mein compiler das auch nicht anderst akzeptieren. also, was tue ich, wenn ich nicht new() verwenden will ?



  • in C++ mußt du den Rückgabewert von malloc casten.


Anmelden zum Antworten