Forum: Mikrocontroller und Digitale Elektronik Verkettete Liste für Mikrocontroller


von golem (Gast)


Lesenswert?

Guten Morgen,

derzeit bin ich dabei eine verkettete Liste auf einem Mikrocontroller zu 
implementieren. Für die Implementierung habe ich folgende Internetseite 
gefunden:
https://perlgeek.de/de/artikel/einfach-verkettete-listen

In meiner Anwendung wird dazu zuerst ein Instanz vom Typ node erzeugt 
und im Anschluss Speicher mit malloc reserviert. Nun möchte ich zwei 
Elemente hinzufügen. Leider funktioniert dies nicht so wie es sein 
sollte. Was mache ich hier falsch?
1
node pnode;
2
pnode = (node)malloc(sizeof(struct list_node));
3
insert_right(pnode, 123);
4
insert_right(pnode, 345);

: Gesperrt durch Moderator
von Dejavu (Gast)


Lesenswert?

Das ist Dir hier Beitrag "Re: Probleme mit Funktion in C" 
von Peter Danegger eigentlich schon gesagt worden.

Vollständiger, compilierbarer Code, der den Fehler zeigt.

Zusätzlich:
Eine Beschreibung inwiefern das tatsächliche Verhalten vom erwarteten 
abweicht und in welcher Weise das festgestellt wurde.
Nicht, wenn die Glaskugeln der Leser in einem Thread versagen, einen 
neuen aufmachen.

Mahlzeit

von golem (Gast)


Lesenswert?

Der folgende Code ist zeigt ein kleines Beispiel:
1
struct list_node
2
{
3
  unsigned int data;
4
  struct List *next;    // Zeiger auf naechstes Element
5
};
6
7
typedef struct list_node* node;
8
9
node insert_right(node list, int data)
10
{
11
  node new_node  = (node) malloc(sizeof(struct list_node));
12
  new_node->data = data;
13
  new_node->next = list->next;
14
  list->next     = new_node;
15
  return new_node;
16
}
17
18
node delete_right(node list)
19
{
20
  node tmp   = list->next;
21
  list->next = tmp->next;
22
  free(tmp);
23
  return list;
24
}
25
26
void main(void)
27
{
28
  node pnode;
29
  pnode = (node)malloc(sizeof(struct list_node));
30
  pnode = insert_right(pnode, 123);
31
  pnode = insert_right(pnode, 345);
32
  pnode = insert_right(pnode, 678);
33
}

Hier werden die Elemente immer überschrieben. Was müsste ich verändern, 
damit immer ein neues Element an das vorhergehendes Element angehängt 
wird?

von Dejavu (Gast)


Lesenswert?

Na danke. CopyNPaste-Programmierer, oder?

Die Elemente werden nicht überschrieben. Sofern ich mich darin irre, 
fehlte aber immer noch die Angabe darüber auf welche Weise Du das 
feststellst.

Du müsstest zunächst einmal C lernen und die Datenstruktur verstehen.

Dann müsstest Du Dir mal darüber klar werden, ob Du nun ein Element 
nach einem gegeben oder vor einem gegebenen Element einhängen 
willst.

Wir sind doch hier nicht die Hausaufgaben-Mafia. Schalte Dein Hirn 
gefälligst ein oder lerne was Anderes.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Du überschreibst ja auch ständig deine Liste. Merk dir nach dem ersten 
malloc mal den Anfang mit einer zweiten “node“.

golem schrieb:
> node pnode;
>   pnode = (node)malloc(sizeof(struct list_node));
node list = pnode;
>   pnode = insert_right(pnode, 123);
>   pnode = insert_right(pnode, 345);
>   pnode = insert_right(pnode, 678);
Dann kannst du die Liste über list durchgehen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

golem schrieb:
> derzeit bin ich dabei eine verkettete Liste auf einem Mikrocontroller zu
> implementieren.

Hoffentlich nicht für einen ATTiny10...

Ich empfehle Dir, das Programmieren von C und solche Programmierkonzepte 
wie verkettete Listen auf auf einem PC zu lernen. Das ist wesentlich 
schmerzfreier.

Wenn Du Dich dann einigermaßen sicher fühlst und Deine PC-Programme auf 
dem PC korrekt arbeiten, dann wende Deine gelernten Dinge auf die 
Programmierung eines µCs an.

von Nop (Gast)


Lesenswert?

malloc + Mikrocontroller = fail.

von Dampf T. (ouuneii)


Lesenswert?

Fuer dynamisches Memory benotigt man einen eher dicken controller, sonst 
wird das nichts. Zudem braucht man kein dynamisches Memory nur fuer ein 
paar Strings.

Was gegen dynamisches Memory spricht : Woher weisst du, dass der 
Speicher zur Verfuegung steht ? Was geschieht, wenn er nicht zur 
Verfuegung steht ? Was machst du gegen Fragmentierung ? Garbagecollector 
? Referencecounting ?

Ich konnte dynamischen Speicher immer vermeiden und bin schon seit 35 
Jahren im Geschaeft.

: Bearbeitet durch User
von Jan K. (jan_k)


Lesenswert?

Nop schrieb:
> malloc + Mikrocontroller = fail.

Quark, sooo grundsätzlich ist das nicht zutreffend. Malloc bedeutet auch 
nicht zwingend, dass wirklich dynamischer Speicher vom Heap angefordert 
wird.

von (prx) A. K. (prx)


Lesenswert?

Jan K. schrieb:
> Quark, sooo grundsätzlich ist das nicht zutreffend. Malloc bedeutet auch
> nicht zwingend, dass wirklich dynamischer Speicher vom Heap angefordert
> wird.

Es wird bei kleinen µCs meist SRAM statt DRAM sein, aber solltest du 
nicht dies gemeint haben: wovon sonst?

: Bearbeitet durch User
von Jan K. (jan_k)


Lesenswert?

A. K. schrieb:
> Jan K. schrieb:
>> Quark, sooo grundsätzlich ist das nicht zutreffend. Malloc bedeutet auch
>> nicht zwingend, dass wirklich dynamischer Speicher vom Heap angefordert
>> wird.
>
> Es wird bei kleinen µCs meist SRAM statt DRAM sein, aber solltest du
> nicht dies gemeint haben: wovon sonst?

Kommt drauf an, wie malloc implementiert ist. Is womöglich haarspalterei 
und bin mir jetzt beim 2. Lesen nicht mehr sicher, ob das nicht auch ne 
Art Heap ist. Aber ich wollte auf einfache malloc Implementationen 
hinaus, die nur Adressen von einem großen statischen Array zurückgeben 
und die ggf Speicher auch nicht mehr freigeben können, siehe zb die 
freertos Implementationen. Aber im Kontext der verketteten Liste macht 
das vermutlich auch keinen Sinn.

Ich wollte eigentlich nur sagen, dass malloc nicht grundsätzlich böse 
ist auf einem uc. Passt aber möglicherweise nicht gut zum topic,daher 
sorry für eventuelle Verwirrung.

von Peter D. (peda)


Lesenswert?

Ich hab bei meinem Scheduler einfach die maximale Anzahl von Elementen 
schon zur Compilezeit festgelegt.
Das spart sogar etwas RAM, da zur Verkettung der Index des nächsten 
Elements reicht (1 Byte).

Beitrag "Wartezeiten effektiv (Scheduler)"

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

In der Regel weiß man bei einem µC-Programm, welche Menge an Daten 
verarbeitet werden müssen. Man kennt die Größe des RAMs, man kennt den 
Bedarf und man weiß, dass kein virtueller Speicher zur Vergügung steht.

Daher können in den meisten aller Fälle sämtliche Daten im Speicher 
vorher statisch festgelegt werden - wie Peter schon andeutete.

Das Beispiel des TOs - eine verkettete Liste - lässt sich mit einem 
simplen statischen Array erschlagen. Wenns aber um das Erlernen des 
Umgangs mit solchen verketteten Listen geht, soll der TO einen PC nehmen 
und keinen µC. Später, wenns dann läuft, kann er das immer noch auf 
einem µC adaptieren... oder doch ganz anders machen, wenn es um eine 
konkrete Anwendung geht.

von (prx) A. K. (prx)


Lesenswert?

Jan K. schrieb:
> Kommt drauf an, wie malloc implementiert ist. Is womöglich haarspalterei
> und bin mir jetzt beim 2. Lesen nicht mehr sicher, ob das nicht auch ne
> Art Heap ist.

Die Funktion malloc() steht geradezu per Definition für dynamische 
Speicherverwaltung per Heap. Ob vom Heap irgendwann einmal Speicher an 
ein Betriebssystem zurück gegeben wird, ist irrelevant.

von Stefan F. (Gast)


Lesenswert?

Auf kleinen Mikrocontroller (wie AVR's) sollte man malloc vermeiden, 
wann immer es geht. Denn die Speicherverwaltung ist dort nicht so 
ausgefuchst, wie man das von aktuellen PC's gewohnt ist.

Früher oder später wirst du dich mit Speicher-Fragmentierung herum 
schlagen müssen.

von Dampf T. (ouuneii)


Lesenswert?

> Früher oder später wirst du dich mit Speicher-Fragmentierung herum
schlagen müssen.

Eher frueher, eigentlich sofort. Dieses Problem faellt nur weg, wenn man 
immer die gleiche Groesse anfordert, dann kann man aber gleich ein Array 
nehmen.

von fop (Gast)


Lesenswert?

1
void main(void)
2
{
3
  node pnode;
4
  pnode = (node)malloc(sizeof(struct list_node));

Normalerweise nimmt man einen Nullzeiger, um eine leere Liste 
anzuzeigen. Keinen leeren Knoten. Wie willst Du den denn schnell 
erkennen ?

Also :
1
void main(void)
2
{
3
  node pnode;
4
  pnode = (node)0;

Das verketten ist seltsam
1
node insert_right(node list, int data)
2
{
3
  node new_node  = (node) malloc(sizeof(struct list_node));
4
  new_node->data = data;
5
  new_node->next = list->next;
6
  list->next     = new_node;
7
  return new_node;
8
}
Der Neuling zeigt auf den bisher ersten und wird zum Ersten :
1
node insert_right(node list, int data)
2
{
3
  node new_node  = (node) malloc(sizeof(struct list_node));
4
  new_node->data = data;
5
  new_node->next = list;
6
  return new_node;
7
}

Hey und die Mikrokontroller heute sind mindestens 8 Mal so schnell wie 
mein C64 damals und haben bald die selben Speichergrößen. Da sind so 
Pauschaltotschlagargumente wie malloc ist nix für die so langsam 
überholt.

von Stefan F. (Gast)


Lesenswert?

>> Auf kleinen Mikrocontroller (wie AVR's) sollte man malloc vermeiden

> Die Mikrokontroller heute sind mindestens 8 Mal so schnell
> wie mein C64

Der wurde allerdings üblicherweise in Assembler oder Basic programmiert.

Welcher kleine Mikrocontroller (wie AVR's) hat denn 64kB RAM?

von Nop (Gast)


Lesenswert?

fop schrieb:
> Hey und die Mikrokontroller heute sind mindestens 8 Mal so schnell wie
> mein C64 damals und haben bald die selben Speichergrößen

Ich hab schon Projekte scheitern sehen, die zuviel mit malloc rumgesaut 
haben, bei denen war 1MB (!) auf dem Board.

Speicherfragmentierung ist nicht bei 64kB kein Ding mehr. Der 
Speicherumfang ist auch egal, entscheidend ist der Adreßraum. Doof nur, 
wenn man keine MMU hat und deswegen der Adreßraum mit dem Speicher 
identisch ist.

Ein anderer Weg, trotz malloc mit verschieden großen Blöcken keine 
Speicherfragmentierung zu haben: man rundet beim Allozieren immer zur 
nächsten Zweierpotenz auf. Damit verschwendet man nie mehr als 50% 
Speicher.

von Holm T. (Gast)


Lesenswert?

Nop schrieb:
> malloc + Mikrocontroller = fail.

Ähäm...darf ich anmerken das Du hier "fail" bist?

Ich habe das Theater mit den verketteten Listen schon mal durch,
eine Art Protokollkonverter in mitten einer seriellen Strippe mit 
Umsortieren der Elemente und deren Anzahl war auch nicht immer gleich..

Verkettete Listen mit malloc() und free() waren der sinnvollste Weg.

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

Stefan U. schrieb:
> Auf kleinen Mikrocontroller (wie AVR's) sollte man malloc vermeiden,
> wann immer es geht. Denn die Speicherverwaltung ist dort nicht so
> ausgefuchst, wie man das von aktuellen PC's gewohnt ist.

Frag mal Jörg hier im Forum, (Mod) wir haben damals den malloc() Kram 
debuggt).

>
> Früher oder später wirst du dich mit Speicher-Fragmentierung herum
> schlagen müssen.

Nicht wenn man einen Plan hat was man macht und irgend wann wieder 
aufräumt.

Gruß,

Holm

von Falk B. (falk)


Lesenswert?

@  Holm Tiffe (holm)

>Ich habe das Theater mit den verketteten Listen schon mal durch,
>eine Art Protokollkonverter in mitten einer seriellen Strippe mit
>Umsortieren der Elemente und deren Anzahl war auch nicht immer gleich..

Auch das kriegt man mit einem statischen Array hin.

>Verkettete Listen mit malloc() und free() waren der sinnvollste Weg.

Ansichstsache. Dein uC, hier ein AVR, hat nur einen sehr begrenzten 
Speicher, und vor allem, die Anwendung ist bekannt und konstant!
Wenn sich da nicht 2 Funktionen gegenseitig um den Speicher streiten, 
braucht man da kein malloc(). Und selsbt dann könnte man das einfacher 
mittels gegenseitiger Zuweisung/Freigabe von statischen Arrays lösen.

von Jim M. (turboj)


Lesenswert?

Stefan U. schrieb:
> Welcher kleine Mikrocontroller (wie AVR's) hat denn 64kB RAM?

Silabs EFM32GG hat bis 1M Flash und 128kB RAM. Als Cortex-M3 mit maximal 
48 MHz ist der noch in der AVR Klasse.

Ein NRF52 von Nordicsemi hat 64 kB RAM (Cortex M4F mit 64MHz + Bluetooth 
Low Energy). Ich würde QFN48 noch als klein bezeichnen.

von W.S. (Gast)


Lesenswert?

golem schrieb:
> derzeit bin ich dabei eine verkettete Liste auf einem Mikrocontroller zu
> implementieren.

Und wozu?
Welchen tatsächlichen Sinn soll das haben?

Und warum machst du das nicht aus eigener Überlegung heraus, sondern 
sammelst lieber irgendwelches Zeug aus den Untiefen des Internets? 
Meinst du, sowas ist auf deinen (nicht genannten) Zweck irgendwie 
passend?

Also, eine doppelt verkettete Liste hat auch auf einem µC gelegentlich 
ihren Sinn - aber nicht per malloc im RAM, sondern als const... im 
Flash. Ich hatte sowas vor Jahren hier im Forum als Menüsystem der 
Lernbetty vorgeturnt. Für sowas wie Menüzwecke im µC hat sowas oftmals 
seinen Sinn.

Wenn du also wirklich an sowas interessiert bist, dann lade dir die 
Lernbetty herunter und studiere dort in der BettyBase die menu.h und 
menu.c sowie bettymenu.inc Dateien. Dann reden wir weiter.

W.S.

von Holm T. (Gast)


Lesenswert?

Falk B. schrieb:
> @  Holm Tiffe (holm)
>
>>Ich habe das Theater mit den verketteten Listen schon mal durch,
>>eine Art Protokollkonverter in mitten einer seriellen Strippe mit
>>Umsortieren der Elemente und deren Anzahl war auch nicht immer gleich..
>
> Auch das kriegt man mit einem statischen Array hin.

Aber nicht wenn der Speicher dann voll ist. Ich habe nicht umsonst den 
Mega644 verwendet damals.

Verstehe mich richtig, das war ne Auftragsarbeit und die war erfolgreich 
und wurde bezahlt.

>
>>Verkettete Listen mit malloc() und free() waren der sinnvollste Weg.
>
> Ansichstsache. Dein uC, hier ein AVR, hat nur einen sehr begrenzten
> Speicher, und vor allem, die Anwendung ist bekannt und konstant!
> Wenn sich da nicht 2 Funktionen gegenseitig um den Speicher streiten,
> braucht man da kein malloc(). Und selsbt dann könnte man das einfacher
> mittels gegenseitiger Zuweisung/Freigabe von statischen Arrays lösen.

Du mußt es ja wissen und scheinst von Jörg nicht viel zu halten denn es 
war auch seiner Ansicht nach die beste Lösung. Außerdem kennst Du Dich 
gut mit der Art Daten aus die ich zu verarbeiten hatte.

Gruß,

Holm

von (prx) A. K. (prx)


Lesenswert?

Jim M. schrieb:
>> Welcher kleine Mikrocontroller (wie AVR's) hat denn 64kB RAM?
> Ich würde QFN48 noch als klein bezeichnen.

Nach dem Motto: malloc darf nur ab QFN64 verwendet werden? ;-)

: Bearbeitet durch User
von Sheeva P. (sheevaplug)


Lesenswert?

golem schrieb:
>
1
> node insert_right(node list, int data)
2
> {
3
>   node new_node  = (node) malloc(sizeof(struct list_node));
4
>   new_node->data = data;
5
>   new_node->next = list->next;
6
>   list->next     = new_node;
7
>   return new_node;
8
> }
9
>
>
> Hier werden die Elemente immer überschrieben. Was müsste ich verändern,
> damit immer ein neues Element an das vorhergehendes Element angehängt
> wird?

Denk' noch einmal intensiv darüber nach, was Deine Funktion 
insert_right() mit den next-Zeigern macht. Was ist der Wert von 
list->next, wo zeigt der Zeiger hin? An welches Element Deiner Liste 
willst Du new_node anhängen?

von Falk B. (falk)


Lesenswert?

@Holm Tiffe (holm)

>> Auch das kriegt man mit einem statischen Array hin.

>Aber nicht wenn der Speicher dann voll ist. Ich habe nicht umsonst den
>Mega644 verwendet damals.

Deine verketteten Listen sparen aber keinen Speicher.

>Verstehe mich richtig, das war ne Auftragsarbeit und die war erfolgreich
>und wurde bezahlt.

Das will ich gar nicht bezweifeln. Jedoch die Aussage, daß es der 
sinnvollste Lösungsansatz war. Wenn du ihn noch "alternativlos" nennst, 
brennt hier die Luft! ;-)

>Du mußt es ja wissen und scheinst von Jörg nicht viel zu halten denn es
>war auch seiner Ansicht nach die beste Lösung.

Das wollte ich in keinster Weise damit ausdrücken. Und da ich das 
Problem im Detail nicht kenne, kann ich auch keine harten Aussagen dazu 
machen.
Es bleibt aber ein Bauchgefühl übrig.

> Außerdem kennst Du Dich gut mit der Art Daten aus die ich zu verarbeiten hatte.

Nicht wahr? ;-)

Immer locker bleiben, ich will deine Lösung nicht schlecht machen, nur 
vor einem drohenden Tunnelblick warnen.
Und gerade bei nur 4kB RAM spricht SEHR viel für ein statisches Array 
mit einer Prise Knoff Hoff.

von Stefan F. (Gast)


Lesenswert?

> Deine verketteten Listen sparen aber keinen Speicher.

Das ist der Springende Punkt. Auf einem PC ist es in der Regel gut, wenn 
Programme nur so viel Speicher belegen, wie sie tatsächlich auch 
benötigen. Denn der Restliche Speicher bleibt für andere Programme frei 
und wird vom OS als Cache verwendet.

Aber auf Mikrocontrollern frage ich mich, wie viele Programme da denn 
laufen. Normalerweise sicher nur eins. Also darf das Programm gut und 
gerne den gesamten freien Speicher belegen (abzüglich Stack).

Mit dynamischer Speicherverwaltung handele ich mir nur unnötigen 
Overhead ein.

von Sheeva P. (sheevaplug)


Lesenswert?

Stefan U. schrieb:
>> Deine verketteten Listen sparen aber keinen Speicher.
>
> Das ist der Springende Punkt.

Das bezweifle ich.

> Aber auf Mikrocontrollern frage ich mich, wie viele Programme da denn
> laufen. Normalerweise sicher nur eins. Also darf das Programm gut und
> gerne den gesamten freien Speicher belegen (abzüglich Stack).
>
> Mit dynamischer Speicherverwaltung handele ich mir nur unnötigen
> Overhead ein.

Richtig ist, daß man sich Overhead einhandelt. Ob dieser unnötig ist, 
bemißt sich nach dem konkreten Anwendungsfall. Eine dynamische 
Speicherallokation hat den Vorteil, daß man den Speicher auch wieder 
deallokieren und dann für andere Zwecke verwenden kann. Wenn ich nun 
also zwei (oder mehr) Funktionen habe, von denen jede mehr als 50% des 
verfügbaren Speichers zu verschiedenen Zeiten und mit verschiedenen 
Datenstrukturen nutzen muß, dann ist dynamische Allokation 
wahrscheinlich die sinnvollste Lösung.

von Stefan F. (Gast)


Lesenswert?

Ja sicher, aber in diesem Fall sorgt die Programmiersprache automatisch 
dafür. Malloc braucht man dazu nicht. Das gilt ja für alle lokalen 
Variablen in Funktionen.

von Falk B. (falk)


Lesenswert?

@ Stefan Us (stefanus)

>Ja sicher, aber in diesem Fall sorgt die Programmiersprache automatisch
>dafür. Malloc braucht man dazu nicht. Das gilt ja für alle lokalen
>Variablen in Funktionen.

Das gilt aber nur für lokale, nicht statische Variablen. Es gibt 
durchaus Fälle, wo stark schwankende Speichernutzung jenseites eines 
Funktionsaufrufs erfolgt. Das kann ggf. mit malloc() besser handhabbar 
sein, muss es aber nicht.

Das Ganze erinnert an die Goto-Diskussion ;-)
In deren Verlauf wurden zwar eineige Argumente pro Goto hervorgebracht, 
u.a. die überraschend exzessive Nutzung in diversen Linuxkerneln, aber 
auch einige abschreckende Beispiele, die ohne Goto mindestens genauso 
gut oder sogar deutlich besser waren.

Beitrag "goto verpönt - was dann nehmen?"

Ich versuchs mal so zu formulieren.

Je kleiner der uC/RAM, umso mehr sollte man von malloc() Abstand nehmen 
und über eine statische Speicheraufteilung nachdenken.

von Holm T. (Gast)


Lesenswert?

Falk B. schrieb:
> @Holm Tiffe (holm)
>
>>> Auch das kriegt man mit einem statischen Array hin.
>
>>Aber nicht wenn der Speicher dann voll ist. Ich habe nicht umsonst den
>>Mega644 verwendet damals.
>
> Deine verketteten Listen sparen aber keinen Speicher.
>
>>Verstehe mich richtig, das war ne Auftragsarbeit und die war erfolgreich
>>und wurde bezahlt.
>
> Das will ich gar nicht bezweifeln. Jedoch die Aussage, daß es der
> sinnvollste Lösungsansatz war. Wenn du ihn noch "alternativlos" nennst,
> brennt hier die Luft! ;-)
>
>>Du mußt es ja wissen und scheinst von Jörg nicht viel zu halten denn es
>>war auch seiner Ansicht nach die beste Lösung.
>
> Das wollte ich in keinster Weise damit ausdrücken. Und da ich das
> Problem im Detail nicht kenne, kann ich auch keine harten Aussagen dazu
> machen.
> Es bleibt aber ein Bauchgefühl übrig.
>
>> Außerdem kennst Du Dich gut mit der Art Daten aus die ich zu verarbeiten hatte.
>
> Nicht wahr? ;-)
>
> Immer locker bleiben, ich will deine Lösung nicht schlecht machen, nur
> vor einem drohenden Tunnelblick warnen.
> Und gerade bei nur 4kB RAM spricht SEHR viel für ein statisches Array
> mit einer Prise Knoff Hoff.

Ich mußte auf einer seriellen Schnittstelle hereinkommende Datensätze 
einlesen, zwischenspeichern, danach analysieren und in anderem Format 
mit anderer Geschwindigkeit auf einer Anderen wieder ausgeben ..damit 
die bestehende EDV mit einem anderen Automaten klar kam.

Die reinkommenden Datensätze bestanden aus verschiedenen Paketen, die 
teils nur numerische Daten enthielten aber unter Umständen auch 
längliche Kommentarstrings, je nach dem was der analyseautomat so 
gemessen hat oder der Bediener zu kommentieren hatte. Es paßte kein 
festes Raster auf die Daten, deshalb habe ich die Sätze nacheinander in 
eine verkettete Liste einsortiert und zur Auswertung dann die Liste 
durchsucht, Werte umgerechnet und anders formatiert den Kladderradatsch 
wieder ausgebeben, das Ganze natürlich mit dem jeweiligen von der 
Gegenseite erwarteten Handshake.
Ich habe die Liste als Datenbank benutzt und abhängig von Satztyp 
Listenelement für Listenelement durchgekämmt. Nachdem der Meßdatensatz 
durch war habe ich die Liste im Speicher wieder frei gegeben und ich 
habe mit Jörg daran gearbeitet die Fragmetierung zu beseitigen. Da die 
Liste nach jedem Datensatz wieder leer war, gabs keine Probleme.

Statische Arrays hätten mich Speicherplatz für Strings gekostet die dann 
u.U. kürzer reingekommen sind als als das maximal Mögliche, oder aber 
ganz gefehlt hätten. Ein festes Raster hat nicht gepaßt.


Was genau sagtest Du spricht da Alles für ein statisches Array?

Gruß,

Holm

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Schon interessant, dass jetzt ein Sonderfall dafür steht, dass man 
unbedingt überall malloc nutzen muss ;)

von Falk B. (falk)


Lesenswert?

@Holm Tiffe (holm)

>Ich mußte auf einer seriellen Schnittstelle hereinkommende Datensätze
>einlesen, zwischenspeichern, danach analysieren und in anderem Format
>mit anderer Geschwindigkeit auf einer Anderen wieder ausgeben ..damit
>die bestehende EDV mit einem anderen Automaten klar kam.

OK.

>Statische Arrays hätten mich Speicherplatz für Strings gekostet die dann
>u.U. kürzer reingekommen sind als als das maximal Mögliche, oder aber
>ganz gefehlt hätten. Ein festes Raster hat nicht gepaßt.

OK.

>Was genau sagtest Du spricht da Alles für ein statisches Array?

Die endliche Größe deines sowieso kleinen RAMs und damit die endliche 
Anzahl max. speicherbarer Datensätze. Ich hätte es wahrscheinlich mit 1 
großen Speicherblock + einem Verwaltungsarray gemacht, in welchem für 
jedes gespeicherte Datenpaket die Adresse, Länge, Typ + diveres Infos 
(so benötigt) drinstehen. Damit kann man die unterschiedlichen Pakete 
lückenlos speichern und irgendwann leicht verarbeiten. Keinerlei 
zwingender Grund für malloc(), free() und mögliche Fragmentierung. 
Möglicherweise spart das sogar noch einen Tick RAM.

Aber es soll jeder nach seiner Facon glücklich werden.

von Holm T. (Gast)


Lesenswert?

Falk B. schrieb:

>
> Die endliche Größe deines sowieso kleinen RAMs und damit die endliche
> Anzahl max. speicherbarer Datensätze.


Wie immer war die Aufgabe ursprünglich ganz einfach..danach wurde die 
Hardware gebaut. Was folgte war ein moving Target, ich kann mich aber 
nicht beschweren, Alles wurde ordentlich bezahlt.

>Ich hätte es wahrscheinlich mit 1
> großen Speicherblock + einem Verwaltungsarray gemacht, in welchem für
> jedes gespeicherte Datenpaket die Adresse, Länge, Typ + diveres Infos
> (so benötigt) drinstehen. Damit kann man die unterschiedlichen Pakete
> lückenlos speichern und irgendwann leicht verarbeiten. Keinerlei
> zwingender Grund für malloc(), free() und mögliche Fragmentierung.
> Möglicherweise spart das sogar noch einen Tick RAM.
>

Das was Du hier beschreibst ist eine verkettete Liste bei der die 
Pointer vor und zurück in einem Array und nicht in der Liste gespeichert 
werden.
Das braucht exakt genau so viel Speicher (Daten + Zeiger bzw Länge), 
wobei Du aber einen Teil des verfügbaren Speichers fest im 
Inhaltsverzeichnisarray verbrätst, egal wie viele Daten kommen hat 
dieses Array immer die selbe Größe und die selbe Anzahl von möglichen 
Einträgen und Du hast schlechtere Karten wenn plötzlich wenige Lange 
Strings kommen... oder mehr kurze Einträge als Dein Array verwalten 
kann.

malloc() und free() bringen immer die Risiko mit das man Bereiche nicht 
wieder frei gibt, oder Zeug frei gibt das nicht existiert/schon frei ist 
etc.. Memory Leaks. Darüber muß man sich im Klaren sein, allerdings ist 
es halt (wie Du gerade siehst) falsch das Zeug von vornherein zu 
verteufeln. Auf die Art und Weise wie ich das gemacht habe besteht auch 
keine Gefahr das die Fragmentierung für weniger werdenden Speicher 
sorgt, weil das Ganze quasi neu initialisiert wurde wenn ein Datensatz 
abgehandelt war.

Logischerweise ging das Ganze nicht sofort und hat Arbeit gemacht, aber 
es arbeitet heute noch zur Zufriedenheit und hat dazu beigetragen die 
malloc Geschichte der AVR-Libc zu debuggen.

> Aber es soll jeder nach seiner Facon glücklich werden.

Freilich doch. Du wußtest es aber von vornherein besser.
Ich werde statischen Speicher verwenden wenn es möglich ist (weil 
weniger anstrengend) aber ich habe keine Angst vor "malloc() and 
friends" auf Micros.

Gruß,

Holm

von Falk B. (falk)


Lesenswert?

@ Holm Tiffe (holm)

>Wie immer war die Aufgabe ursprünglich ganz einfach..danach wurde die
>Hardware gebaut. Was folgte war ein moving Target, ich kann mich aber
>nicht beschweren, Alles wurde ordentlich bezahlt.

Das ist das Wichtigste ;-)

>Das was Du hier beschreibst ist eine verkettete Liste bei der die
>Pointer vor und zurück in einem Array und nicht in der Liste gespeichert
>werden.
>Das braucht exakt genau so viel Speicher (Daten + Zeiger bzw Länge),
>wobei Du aber einen Teil des verfügbaren Speichers fest im
>Inhaltsverzeichnisarray verbrätst, egal wie viele Daten kommen hat
>dieses Array immer die selbe Größe und die selbe Anzahl von möglichen
>Einträgen und Du hast schlechtere Karten wenn plötzlich wenige Lange
>Strings kommen... oder mehr kurze Einträge als Dein Array verwalten
>kann.

Jain. Real wird es diese Extremfälle nicht so oft geben und selbst wenn, 
kann man zu dem Trick greifen, daß man die Pakete vom Speicheranfang 
schreibt, die Pointerinfos aber vom Speicherende, so wie es bei Stack 
und Heap der Fall ist. Damit hat man maximale Flexibilität ;-)

>malloc() und free() bringen immer die Risiko mit das man Bereiche nicht
>wieder frei gibt, oder Zeug frei gibt das nicht existiert/schon frei ist
>etc.. Memory Leaks. Darüber muß man sich im Klaren sein, allerdings ist
>es halt (wie Du gerade siehst) falsch das Zeug von vornherein zu
>verteufeln.

Du missverstehst mich. Ich will es nicht verteufeln, ich will nur für 
eher kompakte Anwendungen auf kleinen uCs die Alternative aufzeigen. 
Rein sachlicher Wettstreit ohne ideologische Scheuklappen. Das deine 
malloc() Version gut funktioniert, will ich gar nicht besteiten.

> Auf die Art und Weise wie ich das gemacht habe besteht auch
>keine Gefahr das die Fragmentierung für weniger werdenden Speicher
>sorgt, weil das Ganze quasi neu initialisiert wurde wenn ein Datensatz
>abgehandelt war.

Also alles freigeben. Ist OK.

>Logischerweise ging das Ganze nicht sofort und hat Arbeit gemacht, aber
>es arbeitet heute noch zur Zufriedenheit und hat dazu beigetragen die
>malloc Geschichte der AVR-Libc zu debuggen.

Naja, immerhin ;-)

>> Aber es soll jeder nach seiner Facon glücklich werden.

>Freilich doch. Du wußtest es aber von vornherein besser.

Nö, aber ich meine, daß immmer mehrere Wege nach ROM führen. Denn es 
gibt IMMER Alternativen(!)

>Ich werde statischen Speicher verwenden wenn es möglich ist (weil
>weniger anstrengend) aber ich habe keine Angst vor "malloc() and
>friends" auf Micros.

Gut.

von Stefan F. (Gast)


Lesenswert?

> Schon interessant, dass jetzt ein Sonderfall dafür steht, dass
> man unbedingt überall malloc nutzen muss ;)

Das habe ich anders verstanden. Der beschriebene Sonderfall sollte nur 
ein Beispiel sein, wo malloc gerechtfertigt ist.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Schön dass ihr jetzt das leidige Thema malloc auf dem µC mal wieder 
durchgekaut habt. Nichts desto Trotz funktioniert sein insert_right wie 
erwartet. Sein einziges Problem ist dass er sich seine Liste immer 
wieder überschreibt.
Das Problem löst sich, indem (wie ich schon oben angemerkt habe) er sich 
den Listenanfang nochmal separat merkt, oder indem er die Zuweisung 
weglässt, z.B. so:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
struct list_node
5
{
6
  unsigned int data;
7
  struct List *next;    // Zeiger auf naechstes Element
8
};
9
10
typedef struct list_node* node;
11
12
node insert_right(node list, int data)
13
{
14
  node new_node  = (node) malloc(sizeof(struct list_node));
15
  new_node->data = data;
16
  new_node->next = list->next;
17
  list->next     = new_node;
18
  return new_node;
19
}
20
21
node delete_right(node list)
22
{
23
  node tmp   = list->next;
24
  list->next = tmp->next;
25
  free(tmp);
26
  return list;
27
}
28
29
void main(void)
30
{
31
  node pnode;
32
  pnode = (node)malloc(sizeof(struct list_node));
33
  pnode->data = 123;
34
  pnode->next = NULL;
35
  // Liste: [123]->NULL
36
37
  insert_right(pnode, 345);
38
  // Liste: [123]->[345]->Null
39
40
  insert_right(pnode, 555);
41
  // Liste: [123]->[555]->[345]->Null
42
43
  insert_right(pnode->next, 111);
44
  // Liste: [123]->[555]->[111]->[345]->Null
45
46
  delete_right(pnode->next);
47
  // Liste: [123]->[555]->[345]->Null
48
}

von Holm T. (Gast)


Lesenswert?

Stefan U. schrieb:
>> Schon interessant, dass jetzt ein Sonderfall dafür steht, dass
>> man unbedingt überall malloc nutzen muss ;)
>
> Das habe ich anders verstanden. Der beschriebene Sonderfall sollte nur
> ein Beispiel sein, wo malloc gerechtfertigt ist.

Mußt Dich nicht wundern, er wollte nur mal nachtreten und erfindet 
deswegen wieder Aussagen die Niemand gemacht hat.

Gruß,

Holm

von Nop (Gast)


Lesenswert?

Holm T. schrieb:
> Nop schrieb:
>> malloc + Mikrocontroller = fail.
>
> Ähäm...darf ich anmerken das Du hier "fail" bist?

Nein, darfst Du nicht. Du darfst als Bastler aber staunend vom Profi 
lernen, daß malloc bei ernsthaften Projekten aus gutem Grund schlichtweg 
verboten ist.

von Holm T. (Gast)


Lesenswert?

Nop schrieb:
> Holm T. schrieb:
>> Nop schrieb:
>>> malloc + Mikrocontroller = fail.
>>
>> Ähäm...darf ich anmerken das Du hier "fail" bist?
>
> Nein, darfst Du nicht. Du darfst als Bastler aber staunend vom Profi
> lernen, daß malloc bei ernsthaften Projekten aus gutem Grund schlichtweg
> verboten ist.

Darf ich das? und der Profi bist Du?

Lachschlapp. Wenn Du weiter gelesen hättest wüßtest Du das ich meine 
Brötchen genau damit verdiene und zwar in der eigenen Firma..

Ich würde Dich nicht mal als Türsteher einstellen mit Deiner 
Auffassungsgabe. Dein Name hier ist wohl Dein Programm?

Gruß,

Holm

von W.S. (Gast)


Lesenswert?

Holm T. schrieb:
> Ich mußte auf einer seriellen Schnittstelle hereinkommende Datensätze
> einlesen, zwischenspeichern, danach analysieren und in anderem Format
> mit anderer Geschwindigkeit auf einer Anderen wieder ausgeben

Ach herrje - und deswegen hast du mit verketten Listen gearbeitet? 
Wirklich?

Ich hätte einen passablen Ringpuffer für die Rx-Daten vorgesehen und 
einen Stack für die im Stream erkannten Dinge und fertig.

Dein Problem ist ja doch (nach deiner eigenen Schilderung) 
input-->Verarbeitung-->Output.

Für so etwas ist eine verkettete Liste schlichtweg das falsche Mittel. 
Es kann ja sein, daß ein Umsortieren innerhalb eines oder zweier (oder 
dreier) Datenblöcke erforderlich ist, aber dafür eine verkettet Liste? 
Sowas benutzt man für Dinge, wo relativ wahlfrei immer wieder auf 
Dinge zugegriffen wird, die sich nicht in ein Array fassen lassen, weil 
sie eben sowas wie Objekte sind. Ist bei dir aber nicht der Fall, denn 
du hast ja nach einem oder zwei Blöcken immer wieder aufgeräumt. Also 
ist ein Zugriff auf auseinanderliegende Objekte nicht erforderlich 
gewesen. Für sowas macht man einen Stack auf, der quasi unerledigte 
Objekte aufnimmt, also einen LiFo-Buffer. Wie gesagt, verkettete Listen 
sind dafür, auf verschiedene Dinge IMMER WIEDER zuzugreifen. Für 
gleiche Dinge benutzt man besser Arrays.

Aber kommen wir mal zum TO zurück: der hat sich schon ewig nicht mehr 
gemeldet, wahrscheinlich hat er gemerkt, daß seine Übung nicht sehr 
praxisrelevant gewesen ist.

W.S.

von Holm T. (Gast)


Lesenswert?

W.S. schrieb:
> Holm T. schrieb:
>> Ich mußte auf einer seriellen Schnittstelle hereinkommende Datensätze
>> einlesen, zwischenspeichern, danach analysieren und in anderem Format
>> mit anderer Geschwindigkeit auf einer Anderen wieder ausgeben
>
> Ach herrje - und deswegen hast du mit verketten Listen gearbeitet?
> Wirklich?

Ja wirklich herrje...

>
> Ich hätte einen passablen Ringpuffer für die Rx-Daten vorgesehen und
> einen Stack für die im Stream erkannten Dinge und fertig.
>

Soso, hättest Du... ich übrigens nicht.

Ich dachte eigentlich das Du mir nach der Sache mit dem Lochstreifen 
nicht mehr so flach kommst, es sieht aber anders aus. Irgendwie steht 
Deine Antwort da noch aus..?

Jeder Abschnitt im Datensatz erforderte ein Handshake nach der 
Berechnung der Prüfsumme und ggf. Wiederholung. Zwischenspeichern in 
einem Buffer ohne weitere Reaktion war so nicht möglich.


> Dein Problem ist ja doch (nach deiner eigenen Schilderung)
> input-->Verarbeitung-->Output.

Nicht ganz..lies nochmal.
>
> Für so etwas ist eine verkettete Liste schlichtweg das falsche Mittel.
> Es kann ja sein, daß ein Umsortieren innerhalb eines oder zweier (oder
> dreier) Datenblöcke erforderlich ist, aber dafür eine verkettet Liste?
> Sowas benutzt man für Dinge, wo relativ wahlfrei immer wieder auf
> Dinge zugegriffen wird, die sich nicht in ein Array fassen lassen, weil
> sie eben sowas wie Objekte sind.

Genau, und das habe ich ja dann auch gemacht.

> Ist bei dir aber nicht der Fall, denn
> du hast ja nach einem oder zwei Blöcken immer wieder aufgeräumt.

Sagen wir mal nach 20 oder 30 Blöcken mit dem besonderen Feature das 
"Fortsetzungsblöcke" existierten die irgendwann nach anderen Daten 
wieder eingeschachtelt wurden.
Der Parser hat dann anhand der Blocktypen in der Liste zur Ausgabe die 
Daten wieder zusammengestellt. Durch dieses Konzept war ich bei der 
Ausgabe extrem flexibel.

> Also
> ist ein Zugriff auf auseinanderliegende Objekte nicht erforderlich
> gewesen.


Eben doch, weil bei der Ausgabe u.U. die Daten des ersten und des 
letzten Datenblocks eines Datensatzes aufeinander folgend ausgegeben 
werden mußten.
Das Lieferformat der Daten war konstant, aber die Ausgabe mußte für 
unterschiedliche Anwender (Kunden) angepaßt werden. Der Auftraggeber 
lebte davon existierende Geräte bei den Kunden durch seine Eigenen zu 
ersetzen und am Vebrauchsmaterial zu verdienen. Daher "moving Target".

> Für sowas macht man einen Stack auf, der quasi unerledigte
> Objekte aufnimmt, also einen LiFo-Buffer. Wie gesagt, verkettete Listen
> sind dafür, auf verschiedene Dinge IMMER WIEDER zuzugreifen. Für
> gleiche Dinge benutzt man besser Arrays.
>

Ich weiß das Du es immer besser weißt und wenn man dann das Gegenteil 
nachweisen kann wirst Du schlagartig still.
Das Projekt liegt mehrere Jahre zurück, heute hätte ich einen ARM 
genommen und hätte viel mehr Speicher zur Verfügung gehabt. Das war 
damals so nicht gegeben. Nichts desto trotz hat meine Lösung mit der 
Liste als Datenbank für arme Leute bestens funktioniert.

Zusammenfassend sag ichs mal so: "Ach herrje.. wirklich Du jetzt auch 
noch?" Du hast mir gerade noch gefehlt...

> Aber kommen wir mal zum TO zurück: der hat sich schon ewig nicht mehr
> gemeldet, wahrscheinlich hat er gemerkt, daß seine Übung nicht sehr
> praxisrelevant gewesen ist.
>
> W.S.

Was auch immer. Eventuell ging ihm auch nur auf die Nerven das er statt 
einer Lösung immer nur gehört hat das sein Problem gar nicht existieren 
darf.

Gruß,

Holm

von Oberlehrer (Gast)


Lesenswert?

1
  pnode->data = 123;
2
  pnode->next = NULL;
3
  // Liste: [123]->NULL
4
5
  insert_right(pnode, 345);
6
  // Liste: [123]->[345]->Null
7
8
  insert_right(pnode, 555);
9
  // Liste: [123]->[555]->[345]->Null
10
11
  insert_right(pnode->next, 111);
12
  // Liste: [123]->[555]->[111]->[345]->Null
13
14
  delete_right(pnode->next);
15
  // Liste: [123]->[555]->[345]->Null

Das ist falsch, die Reihenfolge stimmt nicht. Nichtgenüged!

von Holm T. (Gast)


Lesenswert?

Nop schrieb im Beitrag #4815588:
> Holm T. schrieb:
>> Lachschlapp. Wenn Du weiter gelesen hättest wüßtest Du das ich meine
>> Brötchen genau damit verdiene und zwar in der eigenen Firma..
>
> Du kriegst nichtmal ein einziges Posting hin, ohne ad hominem zu gehen,
> und entsprechend fiel die Antwort aus. Im Übrigen würde ich in so einer
> Pfuschfirma ohnehin nicht anfangen, danke der Nachfrage. Du hast
> offensichtlich keine Erfahrungen mit ernsthaften Projekten, wo Du mit
> der postulierten Lösung nichtmal durchs Codereview gekommen wärest.


Ich zitiere mal:

"malloc + Mikrocontroller = fail."

und nochmal "Im Übrigen würde" und "nichtmal durchs Codereview gekommen 
wärest"

Also zusammengafaßt: Das ist Deine Idee was eventuell passiert wäre, Du 
weißt nichts, hat aber eine vorgefaßte Meinung die wohl auf Deiner 
Unkenntnis basiert, dazu kommt "Nop (Gast)" ist auch Niemand.

Du bist "offensichtlich" wichtig wie ein drittes Knie.

Gruß,

Holm

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

@nop und Andere
Verschwendet nicht eure Zeit, mit dieser hohlm Type kann man nicht 
diskutieren.

Vor allem wie der letzte Post wieder ein Paradebeispiel dafür war wie 
seine Posts ALLE ad hominem gehen.

Kann da nur aus Erfahrung aus meinem MIPS TTL Thread berichten.
Erstmal wirft er einen irgendwelche Sachen an Kopf ohne sich selber 
vorher zu informieren. Wenn man dann Gegenargumente bringt dann werden 
diese für ungültig erklärt oder für an den Haaren herbeigezogen erklärt.
Wenn man Ihm dann mit einem Datenblattausschnitt überführt, dass er Mist 
schreibt, dann wird er richtig persönlich inkl. Gürtellinien 
Unterschreitung.


Zum Thema:
Also ich kenn da genug Firmen wo selbst auf einem größeren ARM Kern mit 
16MB+ ext. RAM ein malloc verbot herscht und sogar der Linker Alarm 
schlägt falls irgendeine Lib auf die Idee kommen sollte das zu nutzen.
Bei Projekten mit kleinem RTOS drunter wird dann dessen 
Speicherverwaltung genutzt. Das sind dann aber meißt mempools, die nur 
gleiche BLockgrößen erlauben. Warum gleich groß sollte einleuchten ;)

von Karl (Gast)


Lesenswert?

Mw E. schrieb:
> Also ich kenn da genug Firmen wo selbst auf einem größeren ARM Kern mit
> 16MB+ ext. RAM ein malloc verbot herscht

Ach herrje. Ich kenne Firmen die kaufen extra einen Controller mit fpu 
und verwenden sie dann nicht weil die Softwarefuzzis Angst haben.
Nur weil es viele dämliche Entscheidungen auf dieser Welt gibt muss man 
es ja nicht nachmachen...

An alle Kritiker und Zweifler: nennt doch Mal konkrete Probleme mit der 
malloc Implementierung der newlib. Mir kommt es so vor als ob alle 
bedenkenträger dieser Welt auf dem wissen von vor zwanzig Jahren 
herumreiten.

Ich verwende c++ und pure virtuelle klassen auch auf dem Controller. 
Objekte werden zum Teil dynamisch erzeugt. Kein Problem damit. Ein paar 
Bytes für die sprungtabelle? Drauf ge*##*en.

von Holm T. (Gast)


Lesenswert?

Mw E. schrieb:
> @nop und Andere
> Verschwendet nicht eure Zeit, mit dieser hohlm Type kann man nicht
> diskutieren.
>
> Vor allem wie der letzte Post wieder ein Paradebeispiel dafür war wie
> seine Posts ALLE ad hominem gehen.

Das kannst Du Dir bitte auch selbst auf die Fahnen schreiben, denn Du 
hast damit angefangen. Die Tatsache das Du etwas nicht kannst (mit mir 
diskutieren) solltest Du nicht gleich auf die Allgemeinheit 
reflektieren. Der Mensch schließt zwar gerne von sich selbst auf Andere, 
man sollte aber dann auch ein ausreichendes Maß an Intelligenz 
mitbringen um Wahrscheinlichkeiten beurteilen zu können.
>
> Kann da nur aus Erfahrung aus meinem MIPS TTL Thread berichten.
> Erstmal wirft er einen irgendwelche Sachen an Kopf ohne sich selber
> vorher zu informieren. Wenn man dann Gegenargumente bringt dann werden
> diese für ungültig erklärt oder für an den Haaren herbeigezogen erklärt.
> Wenn man Ihm dann mit einem Datenblattausschnitt überführt, dass er Mist
> schreibt, dann wird er richtig persönlich inkl. Gürtellinien
> Unterschreitung.
>

Du hattest Gegenargumente, ich habe diese entkräftet und Dir Fragen 
gestellt. Antwort kam keine, aber das nächste Gegenargument usw..
Du hast mich ständig mit neuen Gegenargumenten, die nicht mal durchdacht 
waren beworfen, bist mir aber im Gegenzug jede Antwort auf mein 
Nachhaken schuldig geblieben. Du nennst das Diskussionskultur? Ich 
nicht.
Du ziehst Dich an 3 TTL Gattern hoch und bietest in Gegenzug ganze 
Kuchenbleche voller TTL an..

Es ist ein Unterschied ein Argument "für ungültig zu erklären" wie es 
speziell Deine Art ist, oder aber jedes mal Nachweise heraus zu suchen 
warum das nicht so ist.. es ging ja sogar so weit das ich 
Beschaffungsfragen klären sollte. Im Gegenzug bist Du mir mehr und mehr 
blöde gekommen was sich auch in entsprechenden Antworten nieder schlug.

Wenn wir mal von unter der Gürtellinie sprechen: Wofür hältst Du Dein 
hinterhältiges Nachtreten in Threads die mit Deinem gar Nichts zu tun 
haben? Das ist primitiv mein Lieber.

An Deiner Stelle würde ich mal probieren eine Selbsthilfegruppe der Holm 
geschädigten in Leben zu rufen, evtl. kannst Du ja irgendwo 
EU-Fördermittel beantragen usw...

>
> Zum Thema:
> Also ich kenn da genug Firmen wo selbst auf einem größeren ARM Kern mit
> 16MB+ ext. RAM ein malloc verbot herscht und sogar der Linker Alarm
> schlägt falls irgendeine Lib auf die Idee kommen sollte das zu nutzen.
> Bei Projekten mit kleinem RTOS drunter wird dann dessen
> Speicherverwaltung genutzt. Das sind dann aber meißt mempools, die nur
> gleiche BLockgrößen erlauben. Warum gleich groß sollte einleuchten ;)

So kennst Du solche Firmen? Nenne doch mal ein Beispiel und vor Allem 
möchte ich gerne mal einen Linker kennenlernen der sich derart verhält 
wie Du es erzählst :-)

Was glaubst Du eigentlich wie ein "kleines RTOS" die Speicherverwaltung 
managed? Nicht mit alloca() sondern mit Veilchenduft?

Es ist einfach nur als dümmlich zu betrachten Bibliotheksfunktionen als 
böse zu verteufeln nur aus dem Grund das man sie nicht versteht.
Deine Art zu programmieren ist wahrscheinlich der Grund warum heute 
Betriebssysteme Gigabytes an Speicher zu verschwenden ohne irgendwie 
effizient zu sein.
Wenn Du das Anderswo so gesehen hast, was ich stark bezweifele, dann 
solltest Du mal Dein Umfeld ändern.

Gruß und einen schönen 2. Advent,

Holm

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Für sowas wurden Linkerscripte erfunden, hier ein Beispiel vom ld:
1
mall = 1 - DEFINED(malloc);
2
ASSERT(mall, "malloc fail")
ASSERT wirft nen Fehler und gibt die Nachricht aus, wenn die Variable 0 
ist.
DEFINED gibt 1 zurück wenn das Label definiert ist.

Das kommt dann zurück:
1
mips-elf/bin/ld: malloc fail
2
collect2: Fehler: ld gab 1 als Ende-Status zurück
3
makefile:75: recipe for target 'all' failed
4
make: *** [all] Error 1

Über den Rest diskutier ich mit einem Dogmatiker wie dir nicht, da ich 
auch schonwieder absichtliche Falschinterpreationen lese.

: Bearbeitet durch User
von Holm T. (Gast)


Lesenswert?

Mw E. schrieb:
> Für sowas wurden Linkerscripte erfunden, hier ein Beispiel vom ld:
>
1
> mall = 1 - DEFINED(malloc);
2
> ASSERT(mall, "malloc fail")
3
>
> ASSERT wirft nen Fehler und gibt die Nachricht aus, wenn die Variable 0
> ist.
> DEFINED gibt 1 zurück wenn das Label definiert ist.

Oh, Linkerscripte sind mir durchaus vertraut. Un Du kennst Firmen die 
sowas da drin stehen haben? Welche?

>
> Das kommt dann zurück:
>
1
> mips-elf/bin/ld: malloc fail
2
> collect2: Fehler: ld gab 1 als Ende-Status zurück
3
> makefile:75: recipe for target 'all' failed
4
> make: *** [all] Error 1
5
>
>
> Über den Rest diskutier ich mit einem Dogmatiker wie dir nicht, da ich
> auch schonwieder absichtliche Falschinterpreationen lese.


Das Dogma versuchst u.A. Du doch hier durchzudrücken: Malloc() auf 
Mikros  ist böse.
Das ist Glaube, und kein Wissen, lt. Wikipedia ist  ein Dogmatiker:

"Im Alltagsgebrauch bezeichnet man als Dogmatiker eine Person, die sich 
(im Negativen) stur weigert von bestimmten Grundsätzen abzulassen. Der 
Begriff beschreibt allerdings Theologen, die sich mit dem Fachgebiet der 
Dogmatik befassen."

Es ist Dein Grundsatz mit malloc() von dem Du hier stur nicht abweichen 
willst, ergo bist Du der Dogmatiker nicht ich, weil ich keinen solchen 
beschränkten Grundsatz durchzudrücken versuche, sondern 
malloc(),realloc() und free() nicht als gefährlicher einstufe als andere 
Standardfunktionen auch. Bist Du der, der das "Datenblatt" diesmal nicht 
gelesen hat?


Falschinterpretationen? Du bist wohl dann zufrieden wenn ich mir von Dir 
ans Bein pinkeln lasse und in Ruhe abwarte bis der Stiefel voll ist..ich 
versichere Dir: Dieser Fall wird nicht eintreten, mit Verteidigung 
meinerseits ist schon vor "voll" zu rechnen.

Wenn Du meine Reaktionen nicht magst, höre einfach auf zu versuchen zu 
diskreditieren, dann gibts auch keine Reaktion die Dich schmerzt.
Du müßtest mal versuchen vernünftig und weniger herablassend 
aufzutreten, evtl. könntest Du mit mir dann diskutieren auf fachlicher 
Ebene und das könnte sogar Beiden Spaß machen, aber nach dem ich Dich 
hier 3 Wochen kenne lege ich keinen besonderen Wert mehr darauf mit Dir 
zu kommunizieren.


Gruß,

Holm

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>  ... mir ... Du ... ich ... dir ... ich ... Du ... Dein ... Du ... Du ...
> ich ... Du ... Du ... ich mir ... ich ... Dir ... Du ... meine ... Dich
> ... Du ... Du ... mir ... ich ... Dich ... ich ... Dir ...
Merkt ihr eigentlich, dass es nicht mehr um "die Sache" geht, wenn in 
einem Post arg viele Personalpronomen vorkommen?

: Bearbeitet durch Moderator
von Holm T. (Gast)


Lesenswert?

Ja Lothar ..siehe letzte Mail.
Gruß,

Holm

von Sheeva P. (sheevaplug)


Lesenswert?

Mw E. schrieb:
> Vor allem wie der letzte Post wieder ein Paradebeispiel dafür war wie
> seine Posts ALLE ad hominem gehen.

Nach meiner Wahrnehmung gingen die ad-hominem-Angriffe von "Nop" aus, 
als er Holm als "Bastler" abqualifizierte, der "staunend vom Profi" 
lernen dürfe.

von Sheeva P. (sheevaplug)


Lesenswert?

Karl schrieb:
> An alle Kritiker und Zweifler: nennt doch Mal konkrete Probleme mit der
> malloc Implementierung der newlib.

Das haben sie doch schon gemacht: die einen haben Angst davor, die 
Freigabe des dynamisch allokierten Speiches zu vergessen, und die 
anderen haben Angst vor einer eventuellen Speicherfragmentierung.

von W.S. (Gast)


Lesenswert?

Holm T. schrieb:
> Das Dogma versuchst u.A. Du doch hier durchzudrücken: Malloc() auf
> Mikros  ist böse.
> Das ist Glaube, und kein Wissen,

Jetzt hast DU (Lothar's_Counter++) aber die Scheuklappe auf.

Nochmal: Man kann vekettete Listen durchaus auch auf einem µC benutzen, 
man sollte aber wissen, was man da tut. In den wirklich allermeisten 
Fällen erweist sich sowas als herzlich überflüssig, weil fehlgedacht.

Dazu kommt die zumeist anzutreffende Beschränkung in der Hardware, wo 
man eben nicht den RAM zur Verfügung hat, um damit lustig per malloc 
Platz nach Gusto zu reservieren UND man hat in aller Regel bereits zum 
Übersetzungszeitpunkt alle Informationen, die ein malloc überflüssig 
machen. Das ist eben eine ganz andere Situation als auf dem PC. Eben 
genau deshalb ist malloc und Konsorten auf dem µC suspekt, wer will mag 
auch sagen 'böse'.

Der TO hatte einfach nur einige Beispiele hergenommen, die sich eben auf 
die Verhältnisse auf dem PC beziehen und wollte damit auf einem µC 
starten, ohne wirklich zu verstehen, was das beinhaltet. Das war der 
eigentliche Fehler. Siehe:

golem schrieb:
> node pnode;
> pnode = (node)malloc(sizeof(struct list_node));

Es hat das Reservieren von Speicher wirklich NICHTS mit dem Benutzen von 
verketteten Listen zu tun. Das sind verschiedene Dinge -aber soweit muß 
man mental erstmal vorankommen!

Und nochwas zu dir, Holm (Lothar's_Counter++):
Holm T. schrieb:
> Ich habe die Liste als Datenbank benutzt und abhängig von Satztyp
> Listenelement für Listenelement durchgekämmt. Nachdem der Meßdatensatz
> durch war habe ich die Liste im Speicher wieder frei gegeben und ich
> habe mit Jörg daran gearbeitet die Fragmetierung zu beseitigen. Da die
> Liste nach jedem Datensatz wieder leer war, gabs keine Probleme.

Du hast also nicht die Daten beim Hereinkommen bearbeitet, hast sie auch 
nicht kompakt gespeichert, sondern als verkettete Liste - und du hast 
nach Bearbeitung Probleme gehabt, den Speicher wieder freizukriegen, ja?

Keine weiteren Fragen, Kienzle.

W.S.

von Peter D. (peda)


Lesenswert?

Ich hab von nem Kollegen die AVR-ENC28J60-Lib includiert, der benutzt 
darin auch malloc. Funktioniert, also mache ich mir da keinen Kopp.
Selber habe ich aber noch keine Applikation gehabt, die von malloc 
profitieren würde.

von newlib malloc (Gast)


Lesenswert?

> An alle Kritiker und Zweifler: nennt doch Mal konkrete Probleme mit der
> malloc Implementierung der newlib. Mir kommt es so vor als ob alle
> bedenkenträger dieser Welt auf dem wissen von vor zwanzig Jahren
> herumreiten.


Hallo an alle newlib und malloc Spezialisten, ich verwende auf einen 
STM32 die newlib, jetzt ist es so das in cmsis ein unsigned long 
pulStack[size] definiert ist.
Der wird aber für den Newlib Heap und den initial Stack verwendet. Der 
Newlib Heap wächst von den niedrigen Addressen zu den hohen Addressen 
und der Stack von den hohen Addressen zu den niedrigen Addressen.
das der Stack wächst ist für mich ok aber das der Newlib Heap auch 
undefiniert  wächst ist für mich ein großes Problem eigentlich untragbar 
vorallem weil er in großen Sprüngen wächst und das RAM sehr knapp ist 
und nicht erörtert werden kann wieviel dafür benötigt wird.
Ich hätte für den Nwelin Heap gerne eine definierte Größe die nicht 
überschritten wird, weiß jemand wie das bei Newlib umgesetzt werden 
könnte.
Oder habt Ihr auch dieses Problem und wie geht Ihr damit um?

von OSEK (Gast)


Lesenswert?

https://en.wikipedia.org/wiki/OSEK

es hat einen Grund warum Firmen kein malloc erlauben, es soll 
undefiniertes Verhalten ausgeschlossen werden und das betrifft sehr 
viele Bereiche. Wer im Embedded Bereich tätig ist muss wissen wie er 
ohne malloc auskommt.

von Holm T. (Gast)


Lesenswert?

W.S. schrieb:
> Holm T. schrieb:
>> Das Dogma versuchst u.A. Du doch hier durchzudrücken: Malloc() auf
>> Mikros  ist böse.
>> Das ist Glaube, und kein Wissen,
>
> Jetzt hast DU (Lothar's_Counter++) aber die Scheuklappe auf.
>
> Nochmal: Man kann vekettete Listen durchaus auch auf einem µC benutzen,
> man sollte aber wissen, was man da tut.

Ja, habe ich gemacht.

> In den wirklich _allermeisten_
> Fällen erweist sich sowas als herzlich überflüssig, weil fehlgedacht.
>

Es ist ausschließlich Deine Idee zu denken das ich fehlgedacht habe,
denn Dir fehlen die notwendigen Informationen um beurteilen zu können ob 
das fehlgedacht war oder nicht.
Würde es Dir viel ausmachen Deine Ideen auf die Vorhersage des Ausgangs 
von $Fußballspiel umzulenken, statt auf das was ich vor Jahren 
erfolgreich gemacht habe?

> Dazu kommt die zumeist anzutreffende Beschränkung in der Hardware, wo
> man eben nicht den RAM zur Verfügung hat, um damit lustig per malloc
> Platz nach Gusto zu reservieren UND man hat in aller Regel bereits zum
> Übersetzungszeitpunkt alle Informationen, die ein malloc überflüssig
> machen. Das ist eben eine ganz andere Situation als auf dem PC. Eben
> genau deshalb ist malloc und Konsorten auf dem µC suspekt, wer will mag
> auch sagen 'böse'.

allermeist, zumeist ... aber eben nicht immer.
Ich habe nirgends behauptet das nun alle Welt ständig dynamishen 
Speicher benutzen muß, aber es ist leider völliger Blödsinn das Zeug zu 
verteufeln weil man es entweder nicht versteht oder die Impelmentation 
buggy ist.

Du kannst übrigens Einen darauf lassen das ich genau wußte was ich wann 
und wo wieder freigegeben habe und wie der Fragmentierungszustand des 
Speichers aussah nach jeder Operation an der Liste aussah.

Mir ist das gesamte VM System von Windows suspekt weil ich die bessere 
Arbeitsweise von dem des FreeBSD Systems kenne, trotzdem gehe ich Dir 
nicht mit meinen Ansichten dazu auf die Eier.
>
> Der TO hatte einfach nur einige Beispiele hergenommen, die sich eben auf
> die Verhältnisse auf dem PC beziehen und wollte damit auf einem µC
> starten, ohne wirklich zu verstehen, was das beinhaltet. Das war der
> eigentliche Fehler. Siehe:
>
> golem schrieb:
>> node pnode;
>> pnode = (node)malloc(sizeof(struct list_node));
>
> Es hat das Reservieren von Speicher wirklich NICHTS mit dem Benutzen von
> verketteten Listen zu tun. Das sind verschiedene Dinge -aber soweit muß
> man mental erstmal vorankommen!

Bist Du jetzt auf dem Weg dahin oder was willst Du damit zum Ausdruck 
bringen?
>
> Und nochwas zu dir, Holm (Lothar's_Counter++):
> Holm T. schrieb:
>> Ich habe die Liste als Datenbank benutzt und abhängig von Satztyp
>> Listenelement für Listenelement durchgekämmt. Nachdem der Meßdatensatz
>> durch war habe ich die Liste im Speicher wieder frei gegeben und ich
>> habe mit Jörg daran gearbeitet die Fragmetierung zu beseitigen. Da die
>> Liste nach jedem Datensatz wieder leer war, gabs keine Probleme.
>
> Du hast also nicht die Daten beim Hereinkommen bearbeitet, hast sie auch
> nicht kompakt gespeichert, sondern als verkettete Liste - und du hast
> nach Bearbeitung Probleme gehabt, den Speicher wieder freizukriegen, ja?

Nein.
Wir haben die Bugs aus der malloc() Implementierung von avr-libc 
entfernt.

Es ist recht einfach den Speicher wieder frei zu geben wenn man den 
Pointer zum ersten Listenelement noch hat, evtl. erzähle ich Dir ja was 
Neues...

>
> Keine weiteren Fragen, Kienzle.
>
> W.S.

Keine Antworten mehr für Dich denn: Wieviele Megabyte passen auf eine 
Lochstreifenrolle? Hast Du in Deinem Leben schon mal eine gesehen?

Lothars Counter interessiert mich nicht, er kennt meine Meinung dazu.

Gruß,

Holm

von Marco H. (damarco)


Lesenswert?

Grundsätzlich ist es ja so das solch eine Liste ja keine bestimmte Länge 
hat.

Nun kann man statisch Speicher reservieren wie man meint aber am Ende 
hängen nur 10 nodes in der Liste.

Dynamisch Speicher zu reservieren und auch diesen wieder Freizugeben ist 
gar nicht so unklug.

von Nop (Gast)


Lesenswert?

Sheeva P. schrieb:
> Nach meiner Wahrnehmung gingen die ad-hominem-Angriffe von "Nop" aus,
> als er Holm als "Bastler" abqualifizierte, der "staunend vom Profi"
> lernen dürfe.

Das ist falsch. ICH hatte "mikrocontroller + malloc = fail" geschrieben, 
also zur Sache. Holms erstes Posting ging direkt weg von der Sachebene 
mit "Ähäm...darf ich anmerken das Du hier "fail" bist?"

Bei seinen Angestellten kann Holm es sich vielleicht leisten, die Leute 
direkt persönlich blöd anzumachen (zumindest diejenigen, welche keine 
Alternativen haben) - außerhalb davon hat er kein Druckmittel und bekam 
von mir entsprechend Antwort. Auch das zählt zu den Sachen, die er noch 
lernen kann.

Und seine Idee, ich würde irgendeinen Wert darauf legen, in seiner Bude 
anzufangen, zeigt einfach nur groteske Züge.

von Nop (Gast)


Lesenswert?

newlib malloc schrieb:
> Der
> Newlib Heap wächst von den niedrigen Addressen zu den hohen Addressen
> und der Stack von den hohen Addressen zu den niedrigen Addressen.

Das ist ein Design, was von vornherein schon gefährlich ist, weil sie 
aufeinander zuwachsen und es bei einer Kollision schlimmstenfalls 
nichtmal zu einem Absturz kommt, sondern das System undefiniert 
weiterläuft.

Wenn der Speicherverbrauch beidseits stets im grünen Bereich liegt, 
kommt es natürlich nicht dazu, aber sicherer ist es, so ein Design von 
vornherein zu vermeiden.

Das sollte aber auch eigentlich auch nicht mit der Newlib 
zusammenhängen, sondern vielmehr mit dem Linkerscript. Zumindest stelle 
ich darüber ein, wo der Stack hingelegt wird.

Siehe auch hier:
http://embeddedgurus.com/state-space/2014/02/are-we-shooting-ourselves-in-the-foot-with-stack-overflow/

von Franz (Gast)


Lesenswert?

Nop schrieb:
> newlib malloc schrieb:
>> Der
>> Newlib Heap wächst von den niedrigen Addressen zu den hohen Addressen
>> und der Stack von den hohen Addressen zu den niedrigen Addressen.
>
> Das ist ein Design, was von vornherein schon gefährlich ist, weil sie
> aufeinander zuwachsen und es bei einer Kollision schlimmstenfalls
> nichtmal zu einem Absturz kommt, sondern das System undefiniert
> weiterläuft.
Das Problem gibt es auch ohne head-Nutzung durch malloc.
Und es lässt sich auch nicht wirklich umgehen, da zur Compilezeit nicht 
feststeht, wie intensiv der Stack genutzt wird.

Was machen den die malloc-taboo-Firmen da?
Darf jede Funktion nur einmal aufgerufen werden?

von Holm T. (Gast)


Lesenswert?

Nop schrieb:
> Sheeva P. schrieb:
>> Nach meiner Wahrnehmung gingen die ad-hominem-Angriffe von "Nop" aus,
>> als er Holm als "Bastler" abqualifizierte, der "staunend vom Profi"
>> lernen dürfe.
>
> Das ist falsch. ICH hatte "mikrocontroller + malloc = fail" geschrieben,
> also zur Sache. Holms erstes Posting ging direkt weg von der Sachebene
> mit "Ähäm...darf ich anmerken das Du hier "fail" bist?"
>

Und? Was davon hast Du in den falschen Hals bekommen?
Ich habe ein Beispiel dafür angeführt warum das meine Meinung 
ist..länglich.
Von Dir kam aber dann nur das Geräusch eines laufenden Föhns..

> Bei seinen Angestellten kann Holm es sich vielleicht leisten, die Leute
> direkt persönlich blöd anzumachen (zumindest diejenigen, welche keine
> Alternativen haben) - außerhalb davon hat er kein Druckmittel und bekam
> von mir entsprechend Antwort. Auch das zählt zu den Sachen, die er noch
> lernen kann.

Jetzt hast Dus mir aber gegeben. Ich gehe regelrecht vor Ehrfurcht in 
die Knie..Du tapferer Recke.
>
> Und seine Idee, ich würde irgendeinen Wert darauf legen, in seiner Bude
> anzufangen, zeigt einfach nur groteske Züge.

Beruht ja dann auf Gegenseitigkeit. Du bist ein frech 
herumlamentierender "Niemand" der es einem Bastler gezeigt hat. Bravo 
Anonymus.

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

Nop schrieb:
> newlib malloc schrieb:
>> Der
>> Newlib Heap wächst von den niedrigen Addressen zu den hohen Addressen
>> und der Stack von den hohen Addressen zu den niedrigen Addressen.
>
> Das ist ein Design, was von vornherein schon gefährlich ist, weil sie
> aufeinander zuwachsen und es bei einer Kollision schlimmstenfalls
> nichtmal zu einem Absturz kommt, sondern das System undefiniert
> weiterläuft.
>

Quatsch. Das ist eine Frage der konkreten Implementation, Niemand legt 
so absolut fest wo der Speicherbereich liegt in dem malloc Speicher 
alloziert, den kannst Du auch "nebenan" in einen extra RAM legen, Du 
bist doch Herr über den Linker oder?

> Wenn der Speicherverbrauch beidseits stets im grünen Bereich liegt,
> kommt es natürlich nicht dazu, aber sicherer ist es, so ein Design von
> vornherein zu vermeiden.

Was genau unternimmst Du dann gegen das herunterlaufen des Stackpointers 
in Deine statischen Variablenbereiche?
Ist es geradezu gefährlich einen Stackpointer zu verwenden? Keine 
Function Calls, kein PUSH, POP und keine Exeptions und INTs mehr aber 
dafür sicher?

>
> Das sollte aber auch eigentlich auch nicht mit der Newlib
> zusammenhängen, sondern vielmehr mit dem Linkerscript. Zumindest stelle
> ich darüber ein, wo der Stack hingelegt wird.
>

Ach.

[..]

Gruß,

Holm

von Karl (Gast)


Lesenswert?

Sheeva P. schrieb:
> Das haben sie doch schon gemacht: die einen haben Angst davor, die
> Freigabe des dynamisch allokierten Speiches zu vergessen, und die
> anderen haben Angst vor einer eventuellen Speicherfragmentierung.

Na eben nicht. Ersteres ist ein einfacher Bug und Letzteres ist 
theoretisch möglich. Die newlib mergt aber auch Blöcke wieder so dass 
die Gefahr relativ gering ist.

Natürlich ist es embedded allgemein besser ohne malloc/new auszukommen 
aber es gibt auch vernünftige Anwendungen. Wann immer etwas pauschal 
verteufelt wird sollten die Alarmglocken schrillen.

von chris (Gast)


Lesenswert?

Ein Beispiel: Grbl
Alles sehr schön statisch alloziert.
Nimmt man malloc für gcode line buffer sowie TX buffer und planner kann 
man den Speicher viel effectiver benutzen und man erspart sich einige 
buffer overflow, besonders ärgerlich ist der vom TX buffer.

von Karl (Gast)


Lesenswert?

newlib malloc schrieb:
> Ich hätte für den Nwelin Heap gerne eine definierte Größe die nicht
> überschritten wird, weiß jemand wie das bei Newlib umgesetzt werden
> könnte.

Ja. Das passiert in der Funktion sbrk die du als Low Level Funktion für 
die newlib bereitstellen musst. Bei mir gibt es eine heap.c die dir 
Funktion und den speicher definiert. Damit kann der Bereich erstens im 
linkerscript exakt platziert werden zweitens weiß sbrk wie viel Speicher 
Verfügung steht.

Des weiteren liegt mein Main Stack nicht am Ende des Speichers sondern 
an Anfang. Wenn er überlaufen sollte gibt es einen Fehler der zu einer 
entsprechenden Reaktion führt.

von Karl (Gast)


Lesenswert?

OSEK schrieb:
> es hat einen Grund warum Firmen kein malloc erlauben, es soll
> undefiniertes Verhalten ausgeschlossen werden und das betrifft sehr
> viele Bereiche. Wer im Embedded Bereich tätig ist muss wissen wie er
> ohne malloc auskommt.

Hahaha. Erzähl das Mal Toyota. Osek und trotzdem ins Gras gebissen weil 
der Stack überlief und als Reaktion einfach der entsprechende Task 
angehalten wurde. Dieser ganze Dogmatismus bringt nichts wenn trotzdem 
niemand versteht was im Fehlerfall passiert. Trügerische Sicherheit 
nenne ich das.

von newlib (Gast)


Lesenswert?

Nop schrieb:

>Das ist ein Design, was von vornherein schon gefährlich ist, weil sie
>aufeinander zuwachsen und es bei einer Kollision schlimmstenfalls
>nichtmal zu einem Absturz kommt, sondern das System undefiniert
>weiterläuft.

>Wenn der Speicherverbrauch beidseits stets im grünen Bereich liegt,
>kommt es natürlich nicht dazu, aber sicherer ist es, so ein Design von
>vornherein zu vermeiden.

>Das sollte aber auch eigentlich auch nicht mit der Newlib
>zusammenhängen, sondern vielmehr mit dem Linkerscript. Zumindest stelle
>ich darüber ein, wo der Stack hingelegt wird.



Es hat damit was zu tun:
#undef errno
extern int errno;
extern int  _end;
1
caddr_t _sbrk ( int incr )
2
{
3
  static unsigned char *heap = NULL;
4
  unsigned char *prev_heap;
5
6
  if (heap == NULL) {
7
    heap = (unsigned char *)&_end;
8
  }
9
  prev_heap = heap;
10
11
  heap += incr;
12
13
  return (caddr_t) prev_heap;
14
}

Diese Funktion wird von Newlib benötigt.
Was mich stört ist das die Größe des Heap nicht definiert ist.
Wie sollte das denn besser gelöst werden?

von newlib (Gast)


Lesenswert?

Karl schrieb:
> Ja. Das passiert in der Funktion sbrk die du als Low Level Funktion für
> die newlib bereitstellen musst. Bei mir gibt es eine heap.c die dir
> Funktion und den speicher definiert. Damit kann der Bereich erstens im
> linkerscript exakt platziert werden zweitens weiß sbrk wie viel Speicher
> Verfügung steht.

> Des weiteren liegt mein Main Stack nicht am Ende des Speichers sondern
> an Anfang. Wenn er überlaufen sollte gibt es einen Fehler der zu einer
> entsprechenden Reaktion führt.


Ok, danke. also du hast 2 externe Addressen und nicht nur &_end. Was 
machst du wenn über die Größe des Heap darüberhinaus alloziert wird. Man 
hat dann zumindest einen genau Aussage das der Heap zu ende ist. Was 
soll in diesem Fall die Funktion _sbrk zurückgeben, vermutlich muss 
sowieso ein Reset gemacht werden?

von Nop (Gast)


Lesenswert?

Franz schrieb:
> Und es lässt sich auch nicht wirklich umgehen, da zur Compilezeit nicht
> feststeht, wie intensiv der Stack genutzt wird.

Doch, sicher steht das fest, dafür geht eine worst-case-Stackanalyse. 
GCC hilft einem dabei mit -fstack-usage.

Sofern man keine Rekursion verwendet, gibt's dazu sogar Scripte, die aus 
den GCC-Daten automatisch den Calltree ermitteln und damit den 
Stackverbrauch der Eintrittsfunktion ermitteln. Also bei Singletasking 
den von main(), und bei Multitasking den der Taskfunktionen. Keil haut 
das praktischerweise sogar gleich automatisch mit raus.

Natürlich müssen Interrupts noch dazu addiert werden, und zwar in der 
schlimmstmöglichen Prioritätskette.

Rekursion ist bei ernsthaften Projekten eben deswegen ebenfalls nicht 
erlaubt. Sollte man nicht ohne auskommen, muß man die Auswertung manuell 
machen, das wird dann halt aufwendiger. Man muß sich dann den 
Rekursionspfad anschauen und dessen Verbauch mit N multiplizieren, wenn 
man die Rekursionstiefe hart auf N begrenzt (was man tun sollte). Bzw. 
mit N+1 multiplizieren, je nachdem, wo und wie man den Begrenzungs-Check 
einbaut.

Holm T. schrieb:
> Beruht ja dann auf Gegenseitigkeit.

Das kann ich mal so stehenlasssen. Dann haben wir ja geklärt, daß wir 
einander nicht ausstehen können, und können uns dann auch wieder der 
Technik zuwenden.

Holm T. schrieb:
> den kannst Du auch "nebenan" in einen extra RAM legen, Du
> bist doch Herr über den Linker oder?

Ich schrieb doch, daß das übers Linkerscript festgelegt wird.

Externes RAM ist allerdings auf STM32 relativ langsam, treibt die BOM 
nach oben und schafft zusätzliche Fehlermodi, weswegen es einfacher und 
billiger ist, einen größeren Chip zu nehmen, der gleich ausreichend viel 
onchip-RAM hat.

Aber, ja klar, wenn man klar diskontinuierliche Adreßbereiche für Stack 
und Heap hat, dann ist das zumindest für dieses Problem auch eine 
Lösung.

> Was genau unternimmst Du dann gegen das herunterlaufen des Stackpointers
> in Deine statischen Variablenbereiche?

Ich lege den Stack nach GANZ unten in seinem Speicherbereich. Die 
statischen Variablen liegen dann oberhalb des Stacks. Ein eventueller 
Heap wäre dann nochmal darüber.

Stack Overflow (bzw. Unterlaufen beim descending stack des Cortex-M) 
rennt damit schlichtweg in einen hard fault und führt somit zum Absturz. 
Das ist aber ein klares Fehlerbild, was man loggen kann und sollte. 
Zumindest weiß man dann, daß das Gerät noch ein ernsthaftes Problem hat.

Passiert aber nicht, wenn Stackanalyse zur Testphase sowieso in 
irgendwelchen Checklisten als verpflichtender Punkt steht und ohne den 
entsprechenden Nachweis die SW gar nicht erst freigegeben wird.


newlib schrieb:
> Was mich stört ist das die Größe des Heap nicht definiert ist.

Naja an der Stelle, wo der Heapzeiger inkrementiert wird, kann man ja 
auch noch einen Check auf die Maximalgröße einbauen. Die Frage ist eher, 
was denn die aufrufende Funktion dann tut, und wie man einen Fehler 
zurückgibt (wird da ein Nullpointercheck gemacht?).

Und wie die weitere Kette der dann notwendigen Fehlerbehandlung zu 
machen ist, denn am Ende steht ja ein gescheitertes malloc, was man 
sinnvoll auswerten muß.

von Holm T. (Gast)


Lesenswert?

Nop schrieb:
> Franz schrieb:
>> Und es lässt sich auch nicht wirklich umgehen, da zur Compilezeit nicht
>> feststeht, wie intensiv der Stack genutzt wird.
>
> Doch, sicher steht das fest, dafür geht eine worst-case-Stackanalyse.
> GCC hilft einem dabei mit -fstack-usage.

Diese Analyse ist für die Nutzung des Heap genauso möglich, es gibt 
keinen relevanten Unterschied.

[..]
>
> Holm T. schrieb:
>> Beruht ja dann auf Gegenseitigkeit.
>
> Das kann ich mal so stehenlasssen. Dann haben wir ja geklärt, daß wir
> einander nicht ausstehen können, und können uns dann auch wieder der
> Technik zuwenden.

Auf die Idee hättest Du gerne etwas eher kommen können und den Quark mit 
dem Profi stecken lassen.

> Holm T. schrieb:
>> den kannst Du auch "nebenan" in einen extra RAM legen, Du
>> bist doch Herr über den Linker oder?
>
> Ich schrieb doch, daß das übers Linkerscript festgelegt wird.

Du schriebst das der Heap in den Stack läuft oder der Stack in den Heap.

>
> Externes RAM ist allerdings auf STM32 relativ langsam, treibt die BOM
> nach oben und schafft zusätzliche Fehlermodi, weswegen es einfacher und
> billiger ist, einen größeren Chip zu nehmen, der gleich ausreichend viel
> onchip-RAM hat.
>
> Aber, ja klar, wenn man klar diskontinuierliche Adreßbereiche für Stack
> und Heap hat, dann ist das zumindest für dieses Problem auch eine
> Lösung.

>
>> Was genau unternimmst Du dann gegen das herunterlaufen des Stackpointers
>> in Deine statischen Variablenbereiche?
>
> Ich lege den Stack nach GANZ unten in seinem Speicherbereich. Die
> statischen Variablen liegen dann oberhalb des Stacks. Ein eventueller
> Heap wäre dann nochmal darüber.

..was bei Überlauf auf STM32 zu einer Exeption führt, und auf dem 
Atmega644? Was ist bei der alles ein Micro? Darf der auch eine MMU haben 
die Speicherschutz unterstützt?

>
> Stack Overflow (bzw. Unterlaufen beim descending stack des Cortex-M)
> rennt damit schlichtweg in einen hard fault und führt somit zum Absturz.
> Das ist aber ein klares Fehlerbild, was man loggen kann und sollte.
> Zumindest weiß man dann, daß das Gerät noch ein ernsthaftes Problem hat.
>
> Passiert aber nicht, wenn Stackanalyse zur Testphase sowieso in
> irgendwelchen Checklisten als verpflichtender Punkt steht und ohne den
> entsprechenden Nachweis die SW gar nicht erst freigegeben wird.

Beides sind von Dir angenommenen Voraussetzungen die so keineswegs in 
Reallife existieren müssen. Es ist auch nicht so das das verhalten eines 
Programms durch die Verwendung von malloc prinzipiell nicht determiniert 
wäre.
Fakt bleibt das in beiden Fällen die Kiste oder der Task stecken bleibt 
und Mist macht. Why you need a Saddam when you have a Bill? ..oder USS 
Yorktown fällt mir dazu ein...
>
>
> newlib schrieb:
>> Was mich stört ist das die Größe des Heap nicht definiert ist.
>
> Naja an der Stelle, wo der Heapzeiger inkrementiert wird, kann man ja
> auch noch einen Check auf die Maximalgröße einbauen. Die Frage ist eher,
> was denn die aufrufende Funktion dann tut, und wie man einen Fehler
> zurückgibt (wird da ein Nullpointercheck gemacht?).
>
> Und wie die weitere Kette der dann notwendigen Fehlerbehandlung zu
> machen ist, denn am Ende steht ja ein gescheitertes malloc, was man
> sinnvoll auswerten muß.


Gehen wir konform mit der Ansicht das es egal ist ob den Index eines 
statisches Array über dessen Grenze überläuft oder malloc keinen 
Speicher herbeizaubern kann?

Beides sind Fehlerbedingungen die abgefangen werden sollten, weder 
dynamischer noch statischer Speicher können das Problem verhindern das 
der Speicher simpel alle ist, aber bei dynamischer Allocation habe ich 
den Vorteil das anderswo derzeit nicht benötigter Speicher für eine 
andere Aufgabe zur Verfügung steht, das ist die Basis jedes VM Systems.

Gruß,

Holm

von Nop (Gast)


Lesenswert?

Holm T. schrieb:

> Diese Analyse ist für die Nutzung des Heap genauso möglich, es gibt
> keinen relevanten Unterschied.

Sehe ich nicht so, denn wenn das zur Compilezeit bereits ermittelbar 
wäre, könnte man das auch gleich statisch machen. Zudem ist ja 
keineswegs nur die Nutzung ein Thema, sondern auch noch die 
Fragmentierung, vom variablen Timingverhalten eines Allokators mal ganz 
zu schweigen.

Ich hatte das auch schon, daß die SW je nach Umständen für 
unterschiedliche Sachen recht viel Speicher belegen konnte. Das hab ich 
halt in den Stack gesetzt, mit entsprechend fettem Stackverbrauch - aber 
durch den Calltree konnte ich ja nachweisen, daß die kritischen 
Belegungen nie zugleich auftraten. Fragmentierung und Timing sind dann 
kein Thema mehr.

Ansonsten könnte man auch noch z.B. ein statisches char-Array mit 
entsprechendem Alignment anlegen, denn char darf alles aliasen. 
Natürlich muß man dann sicherstellen, daß es nicht doppelt benutzt wird, 
aber das muß man ja so oder so.

> Auf die Idee hättest Du gerne etwas eher kommen können und den Quark mit
> dem Profi stecken lassen.

Gerne, wenn Du das "Du bist fail" unterlassen hättest. Sei's drum.

> Du schriebst das der Heap in den Stack läuft oder der Stack in den Heap.

Das war die Frage des Vorposters, bei dem das so war. Mein Kommentar 
dazu war dementsprechend, daß man das per Linker anders machen sollte, 
mit Verweis zu dem embeddedgurus-Artikel.

Klar, der Vorteil, wenn man sie im selben Speicherbereich aufeinander 
zulaufen läßt, ist der, daß man dynamisch mal mehr Stack und weniger 
Heap und umgedreht verwenden kann. Ich würde so ein Design aus 
grundsätzlichen Erwägungen aber trotzdem nicht machen.

> ..was bei Überlauf auf STM32 zu einer Exeption führt, und auf dem
> Atmega644?

Auf dem würde ich mich erstmal ins Datenblatt einlesen, welche 
Möglichkeiten man da hat; so ad hoc möchte ich dazu nichts sagen, weil 
das ohen Detailkenntnis nicht fundiert wäre. Dennoch, selbst wenn es 
keine Exception gibt, ist die Aussicht auf data corruption mit 
undefiniertem Verhalten nichts, was ich anstreben würde.

> Was ist bei der alles ein Micro? Darf der auch eine MMU haben
> die Speicherschutz unterstützt?

STM32 hat keine MMU, sondern nur eine MPU, aber beim Zugriff auf 
inexistenten Speicher kommt so oder so eine Exception. Mit MMU sieht die 
Fragmentierungsproblematik natürlich schon anders aus, falls der 
virtuelle Adreßraum ausreichend groß ist.

> Beides sind von Dir angenommenen Voraussetzungen die so keineswegs in
> Reallife existieren müssen.

Ich meinte ja schon, daß ich mit ernsthaften Projekten arbeite, wo 
jedenfalls die Analyse fester Teil der Arbeit ist. Klar, wenn man 
Consumergeräte hat, ist ohnehin alles egal, weil Verbraucher es 
akzeptieren, wenn man das Ding hin und wieder resetten muß. 
Industriekunden akzeptieren das aber nicht.

Wenn sowas passiert, hat Sales bei der nächsten Verkaufsrunde ein 
Verhandlungsproblem und muß mit dem Preis runtergehen. Auch wenn ich 
Festgehalt bekomme, denke ich da über meinen Entwicklungsplatz hinaus an 
die Gesamtfinanzen und was ich persönlich dafür tun kann (z.B. mittels 
gründlicher Arbeit). Auch dann, wenn es mir nicht durch Checklisten 
vorgeschrieben wird.

> Es ist auch nicht so das das verhalten eines
> Programms durch die Verwendung von malloc prinzipiell nicht determiniert
> wäre.

Es hat schon seinen Grund, wieso das nicht nur in MISRA, sondern auch in 
Codingstandards anderweitiger Bereiche mit hohen Anforderungen an die 
Zuverlässigkeit nicht erlaubt ist.

Also zumindest nach MISRA darf man das prinzipiell zwar schon, muß dann 
aber detailiert nachweisen, daß es nicht zu Problemen führt, was einigen 
Aufwand bedeutet - der übrigens bei jedem Release erneut anfällt. Man 
muß sich da echt überlegen, welche Wartungskosten man sich ans Bein 
binden will.

> Fakt bleibt das in beiden Fällen die Kiste oder der Task stecken bleibt
> und Mist macht.

Naja deswegen die Stackanalyse, mit der man nachweist, daß derlei nicht 
passiert. Ohne Rekursion ist das auch relativ einfach machbar und sollte 
ohnehin zum guten Stil gehören.

Ansonsten sollte man halt irgendeine Art von Fallback-Modus ins Design 
planen, was man denn tut, wenn die gewünschte Operation nicht geht. In 
Deinem Fall, mit IO-Daten, wäre beispielsweise ein Protokoll denkbar, 
was mit verlorenen Daten klarkommt. Oder, wenn es mehr etwas wie 
Streaming ist, mit unverändertem Zustand weiterlaufen. Und eine 
Regelschleife sollte derlei ohnehin nicht brauchen.

> Gehen wir konform mit der Ansicht das es egal ist ob den Index eines
> statisches Array über dessen Grenze überläuft oder malloc keinen
> Speicher herbeizaubern kann?

Klar. Wenn man mehr Speicher braucht, als verfügbar ist, hat man immer 
ein Problem, egal wo der Speicher herkommt. Aber bei malloc ist das 
primäre Problem nicht, daß ein Nullpointer zurückkommen kann.

> aber bei dynamischer Allocation habe ich
> den Vorteil das anderswo derzeit nicht benötigter Speicher für eine
> andere Aufgabe zur Verfügung steht, das ist die Basis jedes VM Systems.

Nicht nur VM, das ist auch die Basis von PC-Anwendungen - wenn jede 
Anwendung alles greift, was sie theoretisch mal brauchen könnte, ist das 
Unsinn. Ich schreibe ja hin und wieder auch PC-Tools, und natürlich 
nutze ich dann auch malloc usw., und wenn das nicht klappt, beendet sich 
das Tool halt mit entsprechendem Fehlercode.

Aber PCs haben eine MMU und spätestens seit x64 einen Adreßraum, der 
Fragmentierung zum Nichtproblem werden läßt. Darüberhinaus müssen PCs 
üblicherweise auch keine Echtzeitanforderungen erfüllen.

Zudem haben sie einen interaktiven User, was µCs meistens nicht haben. 
Die stehen da irgendwo verloren draußen in der Welt und müssen ohne 
Hilfe mit einer widrigen Umgebung klarkommen.

von S. R. (svenska)


Lesenswert?

Nop schrieb:
> Ich meinte ja schon, daß ich mit ernsthaften Projekten arbeite, wo
> jedenfalls die Analyse fester Teil der Arbeit ist.

Es gibt eine Welt jenseits von vollzertifiziertgarantierten Programmen, 
und dort gelten andere Regeln. Deswegen ist das noch lange keine 
Kinderkacke. Deine Weltsicht entspricht in der Hinsicht eher 
Scheuklappen.

Mag sein, dass du kein malloc benutzen darfst.
Mag sein, dass du kein printf benutzen darfst.
Mag sein, dass es gute Gründe gegen beides gibt.

Es wird aber immer Fälle geben, wo deren Benutzung anzuraten (oder 
zumindest angemessen) ist. Hör bitte einfach auf, dein berufliches 
Umfeld als unveränderliche Bibelweisheit anzupreisen.

Holm T. schrieb:
> Du bist wohl dann zufrieden wenn ich mir von Dir
> ans Bein pinkeln lasse und in Ruhe abwarte bis der Stiefel voll ist

Und du hör bitte einfach mal auf, bei jeder Kleinigkeit verbal in die 
Luft zu gehen, bringen tut's ja doch nix. Es reicht völlig aus, fachlich 
auf etwas hinzuweisen, deswegen muss man den anderen nicht gleich als 
Idioten beschimpfen - egal, ob es stimmt oder nicht.

Dieses ständige Angepisse nervt nämlich. Von beiden Seiten.

Nop schrieb:
> In Deinem Fall, mit IO-Daten, wäre beispielsweise ein
> Protokoll denkbar, was mit verlorenen Daten klarkommt.

Bei einem reinen Protokollkonverter, wie oben skizziert, darf man davon 
ausgehen, dass die Protokolle auf beiden Seiten feststehen. Sonst müsste 
man ja nicht konvertieren. Duh.

von Marco H. (damarco)


Lesenswert?

Doch es geht schon aber er ist eben statisch und verbraucht Ressourcen 
die nicht genutzt werden.

Damit die Liste trotzdem nicht unendlich lang wird baut man einen 
Counter ein. So hat man die Größe im Blick und kann das Problem vorher 
abfangen.


Das Problem mit printf ist das dieses sehr viel Speicher anfordert und 
möglich weise den nicht Geschützen Teil überschreibt. Wenn man die 
Lebenszeit von Variablen und piontern nicht im Auge hat.


Kurz gesagt wenn man schlecht programmiert kommt es damit zu 
unerwarteten verhalten.

von Stefan F. (Gast)


Lesenswert?

@Karl:
> An alle Kritiker und Zweifler: nennt doch Mal konkrete Probleme

Nicht nötig, es wurde schon genug darüber geschrieben. Man muss es nur 
lesen.

von Marco H. (damarco)


Lesenswert?

Probleme gibt es dann wenn man den Speicher nicht mehr frei gibt oder es 
übertreibt. Also zu viel Speicher fest nagelt und dann Funktionen 
aufruft die ebenfalls viel Speicher benötigen z.Bsp printf.

Da es beim AVR oder ARM um ein Single Core System handelt kann man 
eigentlich immer planen wann was aufgerufen wird.

Man muss sich schon über sein Speicherverbrauch und dessen folgen einig 
sein.

von SittenPolice (Gast)


Lesenswert?

leider hat nen avr halt fast keine ram im vergleich zu stm32 aber die 
stm sind zu schwer mal kurz mit gcc und ner makefile zu proggen

von Holm T. (Gast)


Lesenswert?

S. R. schrieb:
[..]
>
> Holm T. schrieb:
>> Du bist wohl dann zufrieden wenn ich mir von Dir
>> ans Bein pinkeln lasse und in Ruhe abwarte bis der Stiefel voll ist
>
> Und du hör bitte einfach mal auf, bei jeder Kleinigkeit verbal in die
> Luft zu gehen, bringen tut's ja doch nix.

Du wirst damit fertig werden müssen das unser Beider Reizschwellen 
offenbar unterschiedliche Größenordnungen haben.
Ich reagiere wenn man mir allzudoof kommt und das bleibt auch so.

>Es reicht völlig aus, fachlich
> auf etwas hinzuweisen, deswegen muss man den anderen nicht gleich als
> Idioten beschimpfen - egal, ob es stimmt oder nicht.

Mein Firefox meint das das Wort "Idiot" exakt ein einziges Mal in diesem 
Thread vor kommt. (jetzt sicher 2 Mal).

>
> Dieses ständige Angepisse nervt nämlich. Von beiden Seiten.

Da hast Du schon Recht damit und wenn mich was anpißt dann wehre ich 
mich,
das hatte ich doch gerade eben gesagt?

Nop ist in die Luft gegangen als ich schrieb das er mit seiner Meinung 
hier "fail" ist ..eine Meinung von mir die Du durchaus zu teilen 
scheinst.
Danach habe ich mir angehört das ich unqualifizierter Bastler sei und 
später wurde meine Firma hinsichtlich Ihrer Kompetenz durch den Kakao 
gezogen. Das sind Sachen die ich so nicht unkommentiert stehen lasse 
(..lassen kann, weil geschäftsschädigend), ob es Dir nun paßt oder 
nicht.

Hast Du das verstanden?

Nop tritt hier anonym auf und denkt deswegen das er austeilen kann wie 
er will ohne sich selbst in Gefahr zu bringen. Für mich gilt das 
allerdings nicht.

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

Nop schrieb:
> Holm T. schrieb:
>
>
>> Auf die Idee hättest Du gerne etwas eher kommen können und den Quark mit
>> dem Profi stecken lassen.
>
> Gerne, wenn Du das "Du bist fail" unterlassen hättest. Sei's drum.


Das hatte keine andere Bedeutung als Deine Meinung für ungültig und 
falsch zu deklarieren ..aus genau den Gründen die ich später ziemlich 
detailliert auf den Tisch gelegt habe.

Muß ich denn Deiner Meinung sein um zu vermeiden das Du mich als Bastler 
der staunend vom Profi lernen darf titulierst und eine 4ma als 
Frickelbude (oÄ) bezeichnest..öffentlich?

Für Dich mögen ja Grundsätze gelten an die Du Dich zu halten hat, bei 
mir muß das nicht zwangsläufig so sein. Genau deshalb war Deine Aussage 
"fail".

>> Du schriebst das der Heap in den Stack läuft oder der Stack in den Heap.
>
> Das war die Frage des Vorposters, bei dem das so war. Mein Kommentar
> dazu war dementsprechend, daß man das per Linker anders machen sollte,
> mit Verweis zu dem embeddedgurus-Artikel.

Schön..ist aber auch egal. Du gehst hier von genau 2 Architekturen aus 
"PC" bei dem sich die Sache mit VM auch aus Deiner Sicht anders verhält 
und STM32..das scheint das zu sein was Du beruflich machst.
Rate mal warum ich gesagt habe Du sollst Micro mal definieren, die 
Abwesenheit einer MMU im STM32 hätte eventuell zu dieser Aussage führen 
können: "STM32 + komische 'Sicherheitsvorgaben' + malloc + 
Mikrocontroller = fail." hat sie aber nicht. Deine Meinung ist einfach 
nicht allgemeingültig.

[..]
>
>> ..was bei Überlauf auf STM32 zu einer Exeption führt, und auf dem
>> Atmega644?
>
> Auf dem würde ich mich erstmal ins Datenblatt einlesen, welche
> Möglichkeiten man da hat; so ad hoc möchte ich dazu nichts sagen, weil
> das ohen Detailkenntnis nicht fundiert wäre.

Kurz: gar Keine. Der Pointer wrapt einfach.

> Dennoch, selbst wenn es
> keine Exception gibt, ist die Aussicht auf data corruption mit
> undefiniertem Verhalten nichts, was ich anstreben würde.

Es gibt keine data corruption, die Mühle hört einfach auf dem Automaten 
seine Daten abzukaufen wenn die Kapazitätsgrenze erreicht ist weil die 
Liste zu lang wird.

>
>> Was ist bei der alles ein Micro? Darf der auch eine MMU haben
>> die Speicherschutz unterstützt?
>
> STM32 hat keine MMU, sondern nur eine MPU, aber beim Zugriff auf
> inexistenten Speicher kommt so oder so eine Exception. Mit MMU sieht die
> Fragmentierungsproblematik natürlich schon anders aus, falls der
> virtuelle Adreßraum ausreichend groß ist.

Schrieb schon, der Grund der Nachfrage war ein Anderer, ich kenne einige 
STM32.
>
>> Beides sind von Dir angenommenen Voraussetzungen die so keineswegs in
>> Reallife existieren müssen.
>
> Ich meinte ja schon, daß ich mit ernsthaften Projekten arbeite,

Mein Gott!
Ich habe doch nirgends geschrieben das Du dummes Zeug machst (war bei 
Dir aber anders) nur Deine Vorgaben ziehen nicht überall und sind 
deshalb aus unterschiedlichen Gründen nicht allgmeingültig.

> wo
> jedenfalls die Analyse fester Teil der Arbeit ist. Klar, wenn man
> Consumergeräte hat, ist ohnehin alles egal, weil Verbraucher es
> akzeptieren, wenn man das Ding hin und wieder resetten muß.
> Industriekunden akzeptieren das aber nicht.
>
Ehy Du ...es war kein Privatkunde der diese Mimik bei mir bestellt hat.

> Wenn sowas passiert, hat Sales bei der nächsten Verkaufsrunde ein

Sales bin auch ich.

[..]
> Es hat schon seinen Grund, wieso das nicht nur in MISRA, sondern auch in
> Codingstandards anderweitiger Bereiche mit hohen Anforderungen an die
> Zuverlässigkeit nicht erlaubt ist.

Ja, Engstirnigkeit und Unwissen derer die die Standards schreiben.
Du glaubst nicht was es für idiotische Standards gibt und das nicht nur 
für Programmierstandards.

>
> Also zumindest nach MISRA darf man das prinzipiell zwar schon, muß dann
> aber detailiert nachweisen
[..]
>
> Zudem haben sie einen interaktiven User, was µCs meistens nicht haben.
> Die stehen da irgendwo verloren draußen in der Welt und müssen ohne
> Hilfe mit einer widrigen Umgebung klarkommen.

Ich sitze hier vor einem PC der auch mit 100 interaktiven Nutzern kein 
Problem hat und ich habe "headless" Server in Rechenzentren stehen.

Du guckst scheinbar durch einen schmalen Tunnel..

Gruß,

Holm

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

@Holm & @Nop:

Ich bitte Euch, mal tief durchzuatmen und persönlich bezogene 
Bemerkungen zu unterlassen. Man kann durchaus auch ohne Anfeindungen 
diskutieren.

Sollte hier nichts mehr zum eigentlichen Thema kommen, werde ich den 
Thread schließen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
> Sollte hier nichts mehr zum eigentlichen Thema kommen, werde ich den
> Thread schließen.
Es kam nichts...

Wenn jemand meint, er hätte noch was Sachliches, was unbedingt 
geschrieben werden müsste, dann bitte eine PN an mich.

: Bearbeitet durch Moderator
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.