mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verkette Liste


Autor: Rennreh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die lIsteenstruktur
struct LEDVEKTORENLISTE{
  struct LEDVEKTORENLISTE *next;
  struct LEDVEKTORENLISTE *ring_next;
  BYTE *vektor;
}*ledvektorenliste_start,*ledvektorenliste_ende;

Die Funtkion, an welcher das nächste Listenelement hinzugefügt wird.
void add_vektor(BYTE*vektor) {
  struct VEKTORENLISTE  *ptr = ledvektorenliste_ende;
  
  
  if(ptr==NULL) {
    ptr  = malloc(sizeof(struct VEKTORENLISTE));
    ptr->vektor      = vektor;
    vektorenliste_start  = ptr;
    ptr->next      = NULL;
    ptr->ring_next    = ptr;
  }else{
    ptr->next  = malloc(sizeof(struct VEKTORENLISTE));
    ptr->ring_next    = ptr->next;
    ptr          = ptr->next;
    ptr->vektor      = vektor;
    ptr->next      = NULL;
    ptr->ring_next    = ledvektorenliste_start;
  }
}

Der Compilier mag die erste Zeil emit dem Malloc nicht...
ptr  = malloc(sizeof(struct VEKTORENLISTE));
error: invalid application of 'sizeof' to incomplete type 'struct 
VEKTORENLISTE'


Ich bin mir da sehr sicher das der Quellcode so funktionieren sollte, 
ebenfalls sollte der Ausdruck
ptr  = malloc(sizeof(*ptr));
 Funktionieren. Ich hatte vorher mit MSVC programmiert nun nutze ich AVR 
Studio mit avrgcc. Liegt es am GCC compiler ?
Wieso kann der Compiler die Größe des Typs "struct LEDVEKTORENLISTE" 
erkennen ?

mfg

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was jetzt? VEKTORENLISTE oder LEDVEKTORENLIST?

Und wieso groß geschrieben?

Und vor malloc() fehlt der cast.

Und überhaupt!

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

Bewertung
0 lesenswert
nicht lesenswert
Rennreh schrieb:

> Der Compilier mag die erste Zeil emit dem Malloc nicht...
>
ptr  = malloc(sizeof(struct VEKTORENLISTE));
> error: invalid application of 'sizeof' to incomplete type 'struct
> VEKTORENLISTE'

Logo.
deine Struktur heißt LEDVEKTORENLISTE und nicht VEKTORENLISTE


PS: reserviere Namen mit nur Großbuchstaben ausschliesslich für Makros. 
Das ist die übliche Konvention.
Es spricht nichts dagegen, wenn du die Struktur LedVektorenListe nennst. 
Ist doch viel leichter zu lesen als so ein Schwall Grossbuchstaben, in 
dem man sich erst einmal die Wortanfänge optisch suchen muss.

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:

> Und vor malloc() fehlt der cast.

Vorsicht.
In C ist der keine gute Idee.

Der cast ist nur dann angebracht, wenn derselbe Code sowohl in C als 
auch in C++ benutzbar sein soll.

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

Bewertung
0 lesenswert
nicht lesenswert
Noch ein Hinweis:

Wenn du in die Debug-Phase kommst (und das wirst du, du hast da ziemlich 
viele Fehler eingebaut :-), dann male dir die Datenstruktur am Papier 
auf und steppe im Papier deine Operation durch, indem du am Papier 
Pointer einzeichnest bzw. ausradierst.

Autor: Rennreh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja stimmt vielen dank :)

nach den vielen änderungen funktioniert es :)

mfg

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tipp zu strukturen, ich machs immer mit typedef:
typedef struct foo_tt
{
  unsigned char c;
  unsigned int i;
  struct foo_tt *next;
  struct foo_tt *prev;
} foo_t;

foo_t foo;

foo_t *foo2 = (foo *) malloc (10 * sizeof(foo));

name_t kennzeichnet hier immer den typedef, und name_tt den namen der 
struktur, da man den ja in einer verketteten Liste in der struktur 
selbst braucht.

Da man häufig eine Variable benötigt, die sich aus der Struktur ableitet 
(also gleicher Name), kommt man hier nicht in komplikationen, man sieht 
sogar auf den ersten Blick die eindeutige Zuordnung.

Und,
GROSSBUCHSTABEN sind idR. für #defines "reserviert".
variablen schreibt man iR. klein,
Funktionen mit grossem Anfangsbuchstaben,

gemischteWoerterInVariablen und
GemischteWörterInFunktionsNamen schreibt man in camelCase bzw. 
CamelCase.


---
> }*ledvektorenliste_start,*ledvektorenliste_ende;


schöner ist es, die mit einem typedef dann "irgendwo" (an sinnvoller 
stelle) zu deklarieren als im struct. Ist auch besser lesbar.


VG,
/th.

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eben und sizeof() braucht ne Variable und keinen Typ...

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
whoops ...
foo_t *foo2 = (foo_t *) malloc (10 * sizeof(foo_t));

mal wieder zu schnell getippt und edit zeit vorbei :-)

Warum kann man hier eigentlich nur so kurz bearbeiten?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel Platte schrieb:

> Eben und sizeof() braucht ne Variable und keinen Typ...

Geht beides.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel Platte schrieb:
> Eben und sizeof() braucht ne Variable und keinen Typ...

Sorry, aber das ist schlicht Unsinn.

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

Bewertung
0 lesenswert
nicht lesenswert
Die Idee, in das einzelne Strukturelement einen Ring-Pointer einzubauen 
würde ich mir noch einmal überlegen.
* Der Pointer muss bei allen weiteren Operationen korrekt
  nachgezogen werden
* Der Pointer braucht Platz. Wenn schon, dann würde ich diesen Speicher
  in eine doppelte Verkettung investieren. Das vereinfacht das Löschen
  aus der Liste enorm.
* Die Funktionalität 'Liste zu einem Ring' schliessen, ist mit einer
  kleinen Hilfsfunktion bei moderatem zusätzlichen Rechenaufwand unter
  Verwendung des Startzeigers leicht zu implementieren:
LedVektorenListe* NextLed( LedVektorenListe* pNow )
{
  if( !pNow )      // just to be sure
    return NULL;

  if( pNow->next == NULL )
    return ledvektorenliste_start;

  return pNow->Next;
}


void foo( LedVektorenListe* pLoop )
{
  LedVektorenListe* pStartedAt = pLoop;

  do {
    // mach was mit pLoop

    pLoop = NextLed( pLoop );
  } while( pLoop != pStartedAt )
}

* Es spricht auch nichts dagegen, die Liste grundsätzlich immer als
  Ring zu führen. Ob ich das Ende der Liste erkenne, indem ich den
  Next Pointer mit NULL vergleiche, oder ob ich ihn mit dem Start-
  Pointer vergleichen muss, ist gehupft wie gesprungen.

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ A. K. (prx)
@ Stefan Ernst (sternst)

Stimmt, geht beides bei sizeof. Ist ja ganz schön schlau das sizeof...

Autor: Rennreh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Danke für eure tips und Hilfe.

@ Karl heinz Buchegger
[ocde]
* Es spricht auch nichts dagegen, die Liste grundsätzlich immer als
  Ring zu führen. Ob ich das Ende der Liste erkenne, indem ich den
  Next Pointer mit NULL vergleiche, oder ob ich ihn mit dem Start-
  Pointer vergleichen muss, ist gehupft wie gesprungen.
[/code]
Ja das ist wahr, bei 1kb sram sollte ich nicht so herumschlampen ^^
Wenn du in die Debug-Phase kommst (und das wirst du, du hast da ziemlich
viele Fehler eingebaut :-), dann male dir die Datenstruktur am Papier
auf und steppe im Papier deine Operation durch, indem du am Papier
Pointer einzeichnest bzw. ausradierst.

Ist es im Kontroller eigentlich wirklich notwendig allokierten Speicher 
mit malloc wieder freizugeben ?
Die notwendigkeit würde doch nur dann bestehen wenn ein Betriebsystem 
die Speicherverwaltung betreibt. Da auf meinem Atmega8 kein 
Betriebsystem läuft aber malloc serwohl weis wo speicher frei ist, frage 
ich mich gerade wie malloc auf dem kontroller eigentlich arbeitet.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist nicht zwingend notwendig, weder mit noch ohne Betriebssystem.
Nur: wenn du nicht wieder freigibst, aber irgendwann wieder allokieren
willst, ist irgendwann natürlich der Speicher alle.

Deshalb:

- Speicher, der während der gesamten Laufzeit benötigt wird: einmal 
allokieren, allokiert lassen.

- Speicher, den man mal braucht und irgendwann nicht mehr: wieder 
freigeben.

Das hat mit einem Betrübsystem nichts zu tun.

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.