2016-03-23 16 views
2

Dies ist auf einer Mikrocontroller-Plattform, so RAM-Nutzung ist wichtig.Erklären Sie zwei verschiedene Strukturgrößen

Ich habe eine nette kleine Bibliothek, die ich für Ringpuffer verwende. Für den Ringpuffer, erkläre ich eine Struktur typedef:

typedef struct buffer { 
    uint8_t data[BUFFER_LENGTH]; 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
} Buffer; 

Normalerweise brauche ich nur eine davon pro Anwendung, so dass die BUFFER_LENGTH auf einen bestimmten Wert definiert, ist keine große Sache, aber ich habe eine Anwendung, die erfordert zwei von ihnen ... eine von relativ kurzer Länge (32 Bytes) und eine von relativ langer Länge (256 Bytes).

Gibt es eine einfache Technik, die ich verwenden kann, die malloc() nicht beinhaltet, die mir erlauben würde, zwei Variablen von zwei verschiedenen Längen zu deklarieren?

Die denken nur, dass ich mit so weit gekommen sind, um die Daten in der Struktur ein Zeiger, erklären das Array zu machen, wenn ich die Puffer deklarieren, und die Pufferlänge zum typedef Buffer hinzu:

typedef struct buffer { 
    uint8_t dataPtr*; 
    uint16_t length; 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
} Buffer; 

uint8_t dataBuf1[256] 
uint8_t dataBuf2[32] 

Buffer buf1, buf2; 

buf1.dataPtr = dataBuf1; 
buf1.length = 256; 

buf2.dataPtr = dataBuf2; 
buf2.length = 32; 

Das wird funktionieren, aber gibt es eine bessere Lösung?

+0

Die Deklaration der Struktur erfordert keinen zusätzlichen Speicherplatz, sie benötigt keinen Platz, bis Sie sie instanziieren. Da Sie beide brauchen, erklären Sie beide einfach. – KevinDTimm

+0

@KevinDTimm Vielen Dank für das Betrachten. Wenn ich "Buffer buf1" und "Buffer buf2" deklariere, dann teilt mein Compiler allen die volle 'BUFFER_LENGTH' zu. Dies wird funktionell funktionieren, aber wird viel mehr RAM verwenden, als ich interessiert bin. – slightlynybbled

+0

Ja, ich sehe das (besonders nachdem ich @ die Antwort von WeatherVan angeschaut habe). Ich war in meiner Interpretation des Problems – KevinDTimm

Antwort

2

Sie können zwei structs wie folgt definieren:

#define LARGE_BUFFER_LENGTH 256 
#define SMALL_BUFFER_LENGTH 32 

typedef struct buffer { 
    uint16_t buffer_size; 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
    uint8_t data[LARGE_BUFFER_LENGTH]; 
} Large_Buffer; 

typedef struct buffer { 
    uint16_t buffer_size; 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
    uint8_t data[SMALL_BUFFER_LENGTH]; 
} Small_Buffer; 

mit dem data Mitglied bis zum Ende bewegt, und ein buffer_size Mitglied hinzufügen. Sie sollten in der Lage sein, die Handler-Funktionen zu teilen, indem Sie den Zeiger auf den kleineren Typ setzen, um ihn für den Compiler akzeptabel zu machen. C ist es egal, wenn Sie ein Array scheinbar überlaufen lassen, und das Feld buffer_size kümmert sich um den Implementierungsunterschied. Sie würden buffer_size (natürlich initialisiert) verwenden, wo immer Sie zuvor BUFFER_LENGTH verwendet haben.

+0

und, wenn das OP ist so besorgt um Raum (und die Variable ist nur einer von 2 Werten SMALL_ und LARGE_) die Puffergröße könnte nur ein 'char' – KevinDTimm

+0

@KevinDTimm aber OP nicht' malloc' verwenden wollen. –

+0

oder, noch besser, um noch mehr Platz zu sparen, haben Sie eine Union mit den Elementen 'data_small [SMALL_BUFFER_LENGTH]' und 'data_large [LARGE_BUFFER_LENGTH]' – KevinDTimm

1

Wenn Sie nicht möchten, dass die dynamische Zuordnung Sie eine Definition wie verwenden:

typedef struct buffer { 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
    int length; 
    uint8_t data[]; 
} Buffer; 

und dann zwei kompatible definierte Typen:

typedef struct buffer1 { 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
    int length; 
    uint8_t data[LENGHT1]; 
} Buffer1_t; 

und:

typedef struct buffer2 { 
    uint16_t newest_index; 
    uint16_t oldest_index; 
    BufferStatus status; 
    int length; // may be useful... 
    uint8_t data[LENGHT2]; 
} Buffer2_t; 

Dann Sie können Zeiger verwenden, um mit zu spielen:

Buffer *allocate_buffer(int type) { 
    if (type==1) { 
     return (Buffer *)malloc(sizeof(Buffer1_t)); 
    } else ... 
}  

Wenn Sie keine dynamische Zuweisung wünschen, können Sie mit statisch vorbelegten Strukturen spielen.

+0

Die "kompatiblen definierten Typen" sind nicht kompatibel (in C sind Strukturen nur * kompatibel *, wenn sie genau gleich sind). Außerdem müssen Sie verschiedene Struktur-Tags verwenden (nicht 'struct buffer' für alle). –

+0

Es gelten keine Regeln für * kompatible Typen * (Standard 6.2.7) und * flexible Array-Elemente * (6.7.2.1/18). Habe ich sie falsch interpretiert? –

+0

Kompatibilitätsanforderung für Strukturen enthält "Wenn einer mit einem Tag deklariert wird, muss der andere mit dem gleichen Tag deklariert werden.". (Auch die gleiche Mitgliederliste ist nicht ausreichend). Übrigens denke ich, dass deine Idee funktioniert, ich habe nur das Wort "kompatibel" kommentiert. –

Verwandte Themen