Frage

Ich habe dieses Stück Code

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

int main(){
    void *a, *b;

    a = malloc(16);
    b = malloc(16);
    printf("\n   block size (for a): %p-%p : %li", b, a, b-a);

    a = malloc(1024);
    b = malloc(1024);
    printf("\n   block size (for a): %p-%p : %li", b, a, b-a);  
}

Sollte dies nicht die letzte zugeordnet Blockgröße drucken (16 oder 1024)? Es stattdessen druckt 24 und 1032, so dass die Menge an Speicher zugewiesen scheint 8 zusätzliche Bytes zu haben.

Mein Problem ist (vor diesem Testfall machen), dass ich malloc() in einer Funktion (1024 Byte) zu tun, und gibt die zugewiesenen Ergebnis. Wenn die Blockgröße auf die Funktion Rückkehr Überprüfung erhalte ich 516 Blöcke ... und ich verstehe nicht, warum. Ich denke, dies könnte der Grund für die Speicherfehler, die nach tut einige Verarbeitung auf dem zugewiesenen Puffer auftreten:)

Bearbeiten: Ich habe Wie kann ich die Größe eines Arrays von einem Zeiger in C? und scheint dasselbe zu fragen, sorry für reposting.

Ich habe mein Beispiel zu meinem spezifischere Code nochmals gemacht:

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

short int * mallocStuff(long int number, short int base){
    short int *array;
    int size=1024;

    array=(short int*)calloc(1,size);
    //array=(short int*)malloc(size);

    return array;
}

int main(){
    short int **translatedArray;

    translatedArray=malloc(4*sizeof(short int));

    int i;
    for(i=0;i<4;i++){
        translatedArray[i]=mallocStuff(0,0);

        if(i>0)
            printf("\n   block size (for a): %p-%p : %i",
                translatedArray[i], translatedArray[i-1], translatedArray[i]-translatedArray[i-1]);
    }

    return 0;
}

Und der Ausgang ist

   block size (for a): 0x804a420-0x804a018 : 516
   block size (for a): 0x804a828-0x804a420 : 516
   block size (for a): 0x804ac30-0x804a828 : 516

Nach der oben genannten Post, die größer als 1024. Am ist ich falsch?

War es hilfreich?

Lösung

Sie haben einen Fehler. Statt:

translatedArray=malloc(4*sizeof(short int));

Sie sollten

translatedArray=malloc(4*sizeof(short int*));

Beachten Sie die fehlende Zeiger in Ihrem Code. Ich vermute, das ist, wo Ihr beobachtete Verhalten ergibt sich aus.


Sie auch, dass 0x804a420 - 0x804a018 = 1032 bemerken, nicht 516. Die Formel translatedArray[i] - translatedArray[i - 1] gibt Ihnen die Anzahl der Elemente (kurz Ints, oder einfacher, Shorts) zwischen den beiden Adressen, nicht die Anzahl der Bytes .

Andere Tipps

Als erstes macht Malloc keine Garantie, dass zwei aufeinanderfolgende malloc Anrufe aufeinanderfolgende Zeiger zurück.

Zweitens, je nach Ihrer spezifischen Architektur, unterschiedliche Ausrichtung Regeln gelten; manchmal könnte man für ein einzelnes Byte fragen, aber die Architektur bevorzugt Zuweisungen auf 8- oder 4-Byte-Intervallen.

Drittens malloc braucht einige Overhead zu speichern, wie groß der zugeordnete Block ist, etc.

Sie keine Annahmen darüber, was malloc tut Vergangenheit, was die Dokumentation sagt!

Die malloc Funktion ordnet immer etwas mehr als man sich wünschen, um einige Buchhaltungsinformationen zu speichern. Nach allem, wenn Sie free() aufrufen muss es wissen, wie groß der Block ist.

Auch im Allgemeinen malloc Implementierungen werden die gewünschte Größe bis zum nächsten Vielfachen von 8 oder 16 oder einer anderen Rund ish Zahl gerundet werden soll.

Aktualisieren : Die wirkliche Antwort auf Ihre Frage liegt in der Nutzung des short int Typs. Wenn Pointer-Arithmetik zu tun (Subtraktion) zwischen typisierten Zeigern, C und C ++, um den Unterschied in der Nummer zurück die Dinge deuteten auf. Da Sie auf short int verweisen, die zwei Bytes groß ist, kehrte der Wert ist die Hälfte von dem, was man erwartet.

Auf der anderen Seite, malloc weist immer eine bestimmte Anzahl von Bytes , egal, was das Ergebnis werfen danach auf. Versuchen Sie folgendes:

    array=(short int*)malloc(sizeof(short int) * size);

Es gibt keine Garantien, dass zwei malloc Anrufe zurückkehren Blöcke genau zusammengepackt - in der Tat gibt es keine Garantien über das Ergebnis überhaupt, mit der Ausnahme, dass, wenn es nicht NULL ist es zu einem Block mindestens so groß wie der Punkt angefordert werden.

Intern meisten mallocs Halten Daten arbeiten, um sie zu verwalten den Haufen zu helfen. Zum Beispiel könnte dieses 8 Bytes zwei Zeiger enthält - einen Hinweis auf den nächsten Block und einen auf den vorherigen Block. Ich weiß nicht, was diese 8 Bytes sind, weil Sie nicht erwähnt, welches Betriebssystem Sie laufen auf, aber es ist völlig normal für malloc für sich etwas Speicher zu verwenden, hinter den Kulissen.

Einige Verteilern (zB Fenster), um eine Bibliotheksfunktion bieten Blockgröße eines Zeiger gegeben zu entdecken, aber manche nicht, da es ein eher esoterisches Merkmal ist.

Was malloc zurückkehrt, hängt von der Implementierung von malloc und der Architektur. Wie andere schon gesagt haben, werden Sie garantiert zumindest die angeforderte Menge an Speicher, oder NULL zu erhalten. Dies ist auch, warum manchmal, Sie über das Ende eines Arrays schreiben können, und nicht einen Segmentation Fault erhalten. Es ist, weil Sie tatsächlich einen gültigen Zugriff auf diesen Speicher DO haben, die Sie gerade es nicht wissen.

malloc () wird in der Regel durch Aufteilung der verfügbaren Heap in Blöcken unterschiedlicher Größe realisiert. In Ihrem Fall malloc () gibt 2 aufeinander folgenden 1024 (oder 16) Byte Chunks. Der 8-Byte-Raum, den Sie erwähnen, ist von malloc () verwendet, um Informationen Buchhaltung.

Siehe Doug Lea malloc () impl Notizen hier zu verstehen, was in hinter den Kulissen geht:

malloc() wird es eigener Kopf ist.

Ganz zu schweigen davon, dass es keine Garantie dafür, dass zwei aufeinander folgende Zuteilungen an nebeneinander sein, mit zu beginnen.

Wenn malloc etwas anderes als null zurückgibt, dann ist der Speicher, dass es zugeordnet wurde für Ihr Programm hat die Größe, die Sie malloc geben. Unter den Zeiger Differenz zwischen den Rückgabewerten von zwei Differenz nennt einen beliebigen Wert zu malloc haben könnte und hat nichts (auch wenig) mit der Blockgröße des ersten zugeordneten Block zu tun.

Bevor der Zeiger die Größe des folgenden Array steht, die ein 32/64 Bit-Integer (weiß nicht, ob mit oder ohne Vorzeichen)

, so dass die Menge des zugewiesenen Speichers scheint 8 zusätzliches Bytes haben? malloc() Implementierung auf Ihrem System scheint zusätzliches Bytes zuzuteilen Meta-Daten Informationen wie zu erhalten, wie groß Haufen Abschnitt ist, was Adresse beginnt etc info.

Obwohl seine Variiert auf verschiedenen Plattformen. Auf meinem X86 System, Aufteilung malloc() min von 17 Bytes, auch wenn ich malloc(0) bin anfordern.

int main(void) {
    int *p = malloc(0);
    if(p == NULL) {
        /* error handling */
    }
    printf("%d\n",p[-1]);/ *it prints 17 bytes */
    /* some code */
    return 0;
}

malloc () kann zusammenhängenden Speicher zuweisen, aber wenn Ihre Berufung malloc () 2 mal und nicht die Speicher zusammenhängend sein zugeteilt erwarten kann durch Subtraktion zweier Zeiger variabls ...

Allerdings zugewiesenen Speicher der virtuelle Speicher ist, die ein Teil der Kernel-Implementierung ist, Speicherverwaltung (VFS) um genau zu sein. Es kann nicht Anwendungsfunktionalität beeinflussen.

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