2012-05-17 13 views
7

Ich habe einen Puffer und möchte einen Test durchführen, um festzustellen, ob der Puffer genügend Kapazität hat. Finde die Anzahl der Elemente, die ich zum Puffer hinzufügen kann.Wie wird die Größe eines zugewiesenen C-Puffers ermittelt?

char *buffer = (char *)malloc(sizeof(char) * 10); 

Doing a

int numElements = sizeof(buffer); 

10 nicht zurückkehren, irgendwelche Ideen, wie ich dies erreichen kann?

Antwort

3

buffer ist nur ein Zeiger ohne Größenangabe. Allerdings wird die malloc() - Routine die Größe der Zuweisung halten, die Sie gemacht haben, wenn Sie sie freigeben(), wird der richtige Speicherplatz frei. Wenn Sie also nicht in der malloc() -Funktionalität tauchen möchten, empfehle ich Ihnen, die Größe der Zuweisung selbst zu speichern. (Für eine mögliche Implementierung, siehe das Beispiel in der anderen API-Antwort).

11

Sie können einen solchen Test nicht durchführen. Es liegt in Ihrer eigenen Verantwortung, sich daran zu erinnern, wie viel Speicher Sie zugewiesen haben. Wenn Ihnen der Puffer von jemand anderem gegeben wird, verlangen Sie, dass sie auch die Größeninformation weitergeben, und machen Sie es in ihre Verantwortung, den korrekten Wert zu übergeben oder das Programm zum Erliegen zu bringen.

6

Da buffer ein Zeiger (kein Array) ist, gibt der Operator sizeof die Größe eines Zeigers zurück, nicht die Größe des Puffers, auf den er zeigt. Es gibt keinen Standard-Weg, um diese Größe zu bestimmen, so haben Sie die Buchhaltung selbst zu tun (dh daran erinnern, wie viel Sie zugeordnet.)

BTW, es ist das gleiche für

char *p = "hello, world\n"; /* sizeof p is not 13. */ 

Interessanterweise

sizeof "hello, world\n" 

ist 14. Können Sie raten warum?

+12

Übergeben Sie wirklich eine Frage an den Fragesteller? Das ist nicht wirklich, warum wir hier sind ... – Evert

+0

@Jens Nun, ich weiß, dass sizeof() die richtige Größe für String-Literale und Arrays zurückgibt, aber warum? Wo ist die Größeninformation gespeichert? Zum Beispiel gibt char * p = "hallo" die Größe des Zeigers, char p [10] ergibt die Größe von zehn. – Zebrafish

+0

@Evert Wir sind hier, um Antworten zu bekommen, und er gab eine Antwort. Posing Follow-up-Fragen ist ein legitimes Bildungsgerät.Außerdem glaube ich nicht, dass seine Frage Kritik erfordert, weil die Antwort auf seine Frage die Antwort ist, die er gerade gegeben hat, also versteckt er nicht wirklich Informationen. Ich nehme an, man könnte über die Wirksamkeit oder den Wert debattieren, der "eine Übung für den Leser" usw. übrig lässt, aber in diesem Fall ist es ziemlich präzise und relevant. –

0
struct buffer 
{ 
    void 
    *memory 

    size_t 
    length; 
}; 

void *buffer_allocate(struct buffer *b, size_t length) 
{ 
    assert(b != NULL); 

    b->memory = malloc(length) 
    b->length = length; 

     // TRD : NULL on malloc() fail 
     return(b->memory); 
} 

int buffer_valid(struct buffer *b, size_t length) 
{ 
    assert(b != NULL); 

    if(b->memory == NULL or length > b->length) 
    return(0); 

    return(1); 
} 

void *buffer_get(struct buffer *b) 
{ 
    assert(b != NULL); 

    return(b->memory); 
} 

Verwenden Sie die API und nicht malloc/free und Sie können nichts falsch machen.

+0

Wenn Sie wirklich clever sein wollten, könnten Sie Ihr eigenes 'malloc' schreiben, das das System' malloc' verwendet, um vier zusätzliche Bytes zuzuordnen, die dort zugewiesene Länge zu speichern und einen Zeiger nach dieser Länge zurückzuschicken. Dann könnten Sie eine "getSize" -Methode verwenden, die Zeigerarithmetik verwendet, um dies wieder herauszuholen. Sie können Anrufe verwenden, die wie "malloc" und "free" aussehen. –

+0

Ich bin mir nicht sicher, ob das schlau ist - es bedeutet, dass sich dein persönliches malloc jetzt in seinem Verhalten allen anderen unterscheidet. Ich bin zu der Ansicht gekommen, das Anpassen des Kernfunktionsverhaltens ist riskant. Es untermauert alles andere. –

+1

Ich kannte eine Firma, überzog Malloc, so dass alles, was es zugeteilt wurde, auf Freelisten überging, und kostenlos das Element zur Freelist zurückgab. Erschreckend, sowohl was es tut und tatsächlich auch wie es implementiert wurde (nicht überraschend, wenn man bedenkt, wie schlecht die Idee ist) und so tief in den Code eingebettet war, dass es niemals entfernt werden konnte. –

0

sizeof wird verwendet, um die Größe für tatsächliche Objekte zu berechnen, nicht die Zeiger für Objekte im Speicher. Es gibt die Größe von Strukturen oder Primitiven zurück. Ich meine, es wird funktionieren, aber Sie erhalten die Größe des Zeigers, nicht die Struktur, auf die er zeigt. Um die Länge von jeder Art von Array Verwendung zu erhalten:

Strlen (buffer)

+0

Die Verwendung von strlen() funktioniert nur bei Strings (d. H. Endet mit einem NUL-Byte). Im Allgemeinen können Sie nicht erwarten, dass "strlen" Ihnen die Länge eines Arrays gibt. In der Tat ist es umgekehrt: "sizeof" ** gibt Ihnen die Größe eines Arrays. – Jens

+0

Also, der richtige Weg wäre: sizeof (* buffer)? – SpaceBear

+0

Nein, da die Deklaration "char * buffer" ist, ist "sizeof * buffer" "sizeof char", was 1 ist. Es gibt keine Möglichkeit, die Größe eines dynamisch zugewiesenen Puffers zu bestimmen, außer daran, wie Sie malloc/calloc aufgerufen haben/realloc. Aber für ** Arrays ** deklariert wie 'char foo [N]' ist 'sizeof foo'' N'. – Jens

19

Für GNU glibc:

SYNOPSIS 

#include <malloc.h> 
size_t malloc_usable_size (void *ptr); 

BESCHREIBUNG

Die malloc_usable_size() -Funktion gibt die Anzahl der verwendbaren Bytes in dem Block zurück, auf den ptr zeigt, einen Zeiger auf einen Speicherblock, der von malloc (3) oder eine verwandte Funktion.

+0

Hinweis: Dies kann zu einem erheblichen Overhead führen, da es von der malloc-Implementierung abhängig ist. Und es gibt die zugewiesenen Bytes zurück. Um die Anzahl der verfügbaren Elemente zu erhalten, benötigen Sie eine zusätzliche Division. Der Mann sagt eindeutig: "Der von malloc_userable_size() zurückgegebene Wert ist möglicherweise größer als die angeforderte Größe der Zuweisung, da Alignment- und minimale Größenbeschränkungen vorliegen. Obwohl die überschüssigen Bytes von der Anwendung ohne negative Auswirkungen überschrieben werden können, ** ist das nicht gut Programmierpraxis **: Die Anzahl der überschüssigen Bytes in einer Zuweisung hängt von der zugrunde liegenden Implementierung ab. " – Stargateur