mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik struct oder array wählen?


Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Halli,
ich stehe gerade vor einem Problem, bzw. einer Frage die mich grübeln 
lässt.

Ich habe ein Konstrukt vor mir das ich mir so vorstelle:
{ 0, { 9, 30, 1, 255, 1800 } }

Nun kann ich ja ein Array mittels [] initialisieren und später weitere 
Einträge hinzufügen / löschen. Nur klappt das mit dem Initialisieren als 
2D-Array bei mir irgendwie nicht. Und wenn ich das Array fest 
initialisiere als z.B int test[5][5] kann ich doch später keine weiteren 
Einträge hinzufügen ,oder?


Oder erstellt man nun ein struct like:
typedef struct
{
  uint8_t day;
  int *data;
} DATA_STRUCT;

Und lässt den pointer auf ein eindimensionales Array zeigen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg schrieb:
> Halli,
> ich stehe gerade vor einem Problem, bzw. einer Frage die mich grübeln
> lässt.
>
> Ich habe ein Konstrukt vor mir das ich mir so vorstelle:
> { 0, { 9, 30, 1, 255, 1800 } }
>
> Nun kann ich ja ein Array mittels [] initialisieren und später weitere
> Einträge hinzufügen / löschen.

Wo?
In C?

Nein.

> Nur klappt das mit dem Initialisieren als
> 2D-Array bei mir irgendwie nicht. Und wenn ich das Array fest
> initialisiere als z.B int test[5][5] kann ich doch später keine weiteren
> Einträge hinzufügen ,oder?

Das kannst du so nicht.
Arrays sind in C immer fix. Wenn sie erst einmal eine bestimmte Größe 
haben, dann haben sie die bis an ihr Lebensende. Wenn du dynamische 
Größenänderung brauchst, musst du in die dynamische Programmierung 
(malloc/free) rein. Oder aber, du kannst natürlich auch sagen: Das sind 
meine Maximalwerte, über die werde ich nie drüber kommen. Ich 
dimensioniere das Array auf Maximalgröße und benutze halt einige 
Einträge nicht.

> Oder erstellt man nun ein struct like:
> typedef struct
> {
>   uint8_t day;
>   int *data;
> } DATA_STRUCT;
>
> Und lässt den pointer auf ein eindimensionales Array zeigen?

Da erschliesst sich mir jetzt der Zusammenhang nicht ganz, den du da 
andeuten möchtest.

Vielleicht fängst du erst einmal ganz am Anfang zu erzählen an. Bei 
deinem eigentlichen Problem, welches du lösen möchtest und nicht bei dem 
Löungsversuch der dir Probleme bereitet.

Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Args, sorry....
WinAVR und nen mega168

das array soll halt datums / zeit-einträge halten

wobei die erste zahl den wochentag darstellen soll und der zweite 
eintrag, ein paar zeit-angaben. wenn ich nun z.B mit data[7][50] 
initialisiere, dann nutze ich schon sehr viel speicherplatz.

laut makefile vor einem test:
Data:        796 bytes (77.7% Full)
(.data + .bss + .noinit)

vorgesehen ist das man die werte mittels taster und lcds verändern kann, 
daher weiss ich nicht ob ich es vielleicht auch auslagern könnte ( 
PROGMEM ) und so wieder ein wenig speicherplatz einzusparen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> taster und lcds verändern kann,
> daher weiss ich nicht ob ich es auch auslagern könnte (PROGMEM )
Im Progmem kannst du nichts mehr ändern (oder nur mit viel Aufwand)...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg schrieb:

> vorgesehen ist das man die werte mittels taster und lcds verändern kann,
> daher weiss ich nicht ob ich es vielleicht auch auslagern könnte (
> PROGMEM ) und so wieder ein wenig speicherplatz einzusparen.

Nein.
Das geht nicht (zumindest nicht simpel)
PROGMEM ist für dein Programm als absolut konstant und unveränderlich 
anzusehen. (Es gibt Ausnahmen, aber die sind sicherlich zu kompliziert).

Zum Problem:
Wenn du keine vernünftige Abschätzung machen kannst, bzw. mit dieser 
Abschätzung nicht leben kannst, weil sie zuviel Speicher verbraucht, 
dann wirst du wohl oder übel auf malloc/free ausweichen müssen, auch 
wenn man das eigentlich nicht möchte.

Die Anzahl der Tage ist ja fix, so wie ich das sehe. Die Woche hat nun 
mal nicht mehr als 7 Tage.
Also reicht es sich ein Array von 7 Pointern anzulegen, wobei jeder 
Pointer auf ein dynamisch allokiertes Array von Werten zeigt. Und 
natürlich muss es noch einen Mechanismus geben, der einem sagt, wieviele 
Einträge zur Zeit gerade allokiert sind.

Also sowas
struct Entry
{
  uint8_t nrAllocated;     // Anzahl momentan allokierter Einträge
  int*    Values;          // die Werte selber
};

Davon brauchst du 7 Stück, für jeden WOchentag einen
struct Entry Data[7];

Und du allokierst zb für Montag 3 Werte
#define MONDAY    0
#define TUESDAY   1
#define WEDNESDAY 2
#define THURSDAY  4
#define FRIDAY    5
#define SATURDAY  6
#define SUNDAY    7

void Init()
{
  uint8_t i;

  for( i = 0; i < sizeof(Data)/sizeof(*Data); ++i ) {
    Data[day].Values = NULL;
    Data[day].nrAllocated = 0;
  }
}

uint8_t Allocate( uint8_t day, uint8_t nrValues )
{
  struct Entry* newData = realloc( Data[day].Values, nrValues * sizeof( *Entry.Values ) );

  if( newData == NULL ) {     // Out of memory
        // tja. Was soll jetzt geschehen
    return FALSE;
  }

  Data[day].Values = newData;
  Data[day].nrAllocated = nrValues;

  return TRUE;
}

int main()
{
  Init();

  if( Allocate( MONDAY, 3 ) ) {
    // Allokierung erfolgreich
    Data[MONDAY].Values[0] = 28;
    Data[MONDAY].Values[1] = 56;
    Data[MONDAY].Values[2] = 178;
  }

  ....

  // Fuer Montag kommen noch 2 Werte dazu
  uint8_t sizeNow = Data[MONDAY].nrAllocated;
  if( Allocate( MONDAY, sizeNow + 2 ) ) {
    Data[MONDAY].Values[sizeNow] = 876;
    Data[MONDAY].Values[sizeNow + 1] = 23;
  }

  ...

  // Alle Werte für Montag
  for( i = 0; i < Data[MONDAY].nrAllocated; ++i )
    // mach was mit Data[MONDAY].Values[i]


Autor: Georg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,
das ist mal ein Anstoss :) Nachdem ich heute den Tag über an zwei 
anderen Sachen schier schon fast verzweifelt bin, werde ich das gleich 
mal testen und schauen wie sich mein Speicher verhält :)

Bzw. ich muss dann mal durchrechnen wieviele Einträge ich machen kann.

Ich sage schon einmal im vorraus danke.

Gruss

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.