Frage

Wenn ich den Code unten versuche, funktioniert er gut. Vermisse ich etwas?

main()
{
    int *p;
    p=malloc(sizeof(int));
    printf("size of p=%d\n",sizeof(p));
    p[500]=999999;
    printf("p[0]=%d",p[500]);
    return 0;
}

Ich habe es mit malloc (0*sizeof (int)) oder irgendetwas ausprobiert, aber es funktioniert gut. Das Programm stürzt nur ab, wenn ich Malloc überhaupt nicht benutze. Selbst wenn ich 0 Speicher für das Array P zuteile, werden Werte immer noch richtig gespeichert. Warum kümmere ich mich dann überhaupt um Malloc?

War es hilfreich?

Lösung

Es könnte erscheinen gut arbeiten, aber es ist überhaupt nicht sehr sicher. Durch das Schreiben von Daten außerhalb des zugewiesenen Speicherblocks überschreiben Sie einige Daten, die Sie nicht sollten. Dies ist eine der größten Ursachen für Segfaults und andere Speicherfehler, und was Sie damit beobachten, dass es in diesem kurzen Programm zu funktionieren scheint, ist es so schwierig, die Ursache zu jagen.

Lesen Dieser Artikel, Insbesondere der Teil zur Korruption des Gedächtnisses, um das Problem zu verstehen.

Valgrind ist ein hervorragendes Werkzeug zur Analyse von Speicherfehlern wie das, die Sie bereitstellen.

@David hat einen guten Kommentar gemacht. Vergleichen Sie die Ergebnisse des Laufens dein Code zu rennen der folgende Code. Beachten Sie, dass der letztere zu einem Laufzeitfehler (ohne nützliche Ausgabe!) Auf ideone.com (klicken Sie auf Links), während er ersteren mit dem Erfolg erfolgreich ist.

main()
{
    int *p;
    p=malloc(sizeof(int));
    printf("size of p=%d\n",sizeof(p));
    p[500]=999999;
    printf("p[0]=%d",p[500]);
    p[500000]=42;
    printf("p[0]=%d",p[500000]);
    return 0;
}

Andere Tipps

Wenn Sie keinen Gedächtnis zuweisen, hat P Müll darin, also wird das Schreiben wahrscheinlich fehlschlagen. Sobald Sie einen gültigen Malloc -Anruf getätigt haben, zeigt P auf einen gültigen Speicherort und Sie können ihn schreiben. Sie überschreiben das Gedächtnis, an das Sie nicht schreiben sollten, aber niemand wird Ihre Hand halten und Ihnen davon erzählen. Wenn Sie Ihr Programm und einen Speicherdebugger wie Valgrind ausführen, wird es Ihnen sagen. Willkommen bei C.

Das Schreiben des Ende Ihres Gedächtnisses ist undefined Behavior ™, was bedeutet, dass alles passieren kann- einschließlich Ihres Programms, das so funktioniert, als wäre das, was Sie gerade getan haben, vollkommen legal. Der Grund für Ihr Programm, das so läuft, als hätten Sie es getan malloc(501*sizeof(int)) sind vollständig implementierungsspezifisch und können tatsächlich spezifisch für alles sein, einschließlich der Mondphase.

Dies liegt daran, dass P eine Adresse zugewiesen wird, unabhängig davon, welche Größe Sie mit malloc () verwenden. Obwohl Sie mit einer Nullgröße einen ungültigen Speicher verweisen würden, wenn der Speicher nicht zugewiesen wurde, kann er jedoch an einem Ort liegen, der keinen Programmabsturz verursachen würde, obwohl das Verhalten nicht definiert wird.

Wenn Sie nicht malloc () nicht verwenden, wird dies auf einen Gewichtsort und Versuch, Zugang zu geben, der wahrscheinlich einen Programmabsturz verursacht.

Ich habe es mit malloc (0*sizeof (int)) ausprobiert

Laut C99, wenn die Größe an übergeben wird malloc IS 0, eine C-Laufzeit kann entweder einen Nullzeiger zurückgeben, oder die Zuordnung verhält sich so, als ob die Anfrage für die Allokation ohne Null vorliegt, außer dass der zurückgegebene Zeiger nicht Dereferenzierung sein sollte. Es ist also die Implementierung definiert (z. B. einige Implementierungen geben einen Puffer mit Null-Länge zurück) und in Ihrem Fall keinen Nullzeiger zurück Könnte einen Nullzeiger zurückbekommen.

Wenn Sie malloc () anrufen, wird ein kleiner Speicherback für Sie aus einer größeren Seite geschnitzt.

    malloc(sizeof(int));

Zuweist nicht 4 Bytes auf einer 32-Bit-Maschine (der Allocator pads es bis zu einer Mindestgröße) + Größe von Haufen Metakaten, die zum Verfolgen des Chunks durch seine Lebensdauer verwendet werden oder frei vom Allocator). hxxp: //en.wikipedia.org/wiki/malloc oder insbesondere hxxp: //en.wikipedia.org/wiki/malloc#dlmalloc_and_its_derivatives, wenn Sie dies unter Linux testen.

Das Schreiben über die Grenzen Ihres Chunks hinaus bedeutet also nicht unbedingt, dass Sie abstürzen werden. Bei P+5000 schreiben Sie nicht außerhalb der Grenzen der für diesen anfänglichen Teil zugewiesenen Seite, sodass Sie technisch an eine gültige zugeordnete Adresse schreiben. Willkommen bei Memory Corruption.http://www.google.com/search?sourceid=chrome&ie=utf-8&q=heap+overflows

Unser Checkpointer Tool kann diesen Fehler erkennen. Es weiß, dass die Zuweisung von P zu einem Teil von 4 Bytes war, und daher wird die Aufgabe erfolgt, sie liegt außerhalb des Bereichs, für den P zugewiesen wurde. Es wird Ihnen sagen, dass die P [500] -Strieb falsch ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top