www.mikrocontroller.net

Forum: Compiler & IDEs zusammhängendes Speicherfeld reservieren


Autor: josefk (nologin?) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich überlege gerade wie man denn zusammenhängenden Speicher reserviert? 
malloc() ist da ja keine Lösung, daher will ich einfach ein Byte- 
Struct- etc. Array anlegen, je nachdem was ich gerade brauche, und dann 
die Adresse des Anfangs des Feldes an einen Pointer übergeben. Danach 
sollte ich ja mittels meinarray[i] darauf zugreifen können?!

Jetzt aber noch eine Frage.

Ich deklariere irgendwo mein Array und meinen Pointer darauf als globale 
Variable:
extern char cbuffer[];
extern char *p_cbuffer;
Dann definiere ich diese Werte in meiner main.c und in einer 
Unterfunktion
//main.c
char *p_cbuffer = 0;
//Funktion in einer anderen .c, die von main.c aufgerufen wird
char cbuffer[50];
p_cbuffer = &cbuffer;

Funktioniert das? Bzw. bleibt mir das Speicherfeld nach Verlassen der 
Funktion erhalten?
Ich bin mir da nicht wirklich sicher.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum ist malloc() keine lösung?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
josefk (nologin?) wrote:

> ich überlege gerade wie man denn zusammenhängenden Speicher reserviert?
> malloc() ist da ja keine Lösung, ...

Warum nicht? Es ist vielleicht nicht die beste Lösung, aber "keine"?

extern char cbuffer[];
extern char *p_cbuffer;
> Dann definiere ich diese Werte in meiner main.c und in einer
> Unterfunktion
//main.c
char *p_cbuffer = 0;
//Funktion in einer anderen .c, die von main.c aufgerufen wird
char cbuffer[50];
p_cbuffer = &cbuffer;
>
> Funktioniert das? Bzw. bleibt mir das Speicherfeld nach Verlassen der
> Funktion erhalten?

Nein, geht so nicht. Du definierst in der Funktion eine lokale Variable, 
die genauso heißt wie die globale (cbuffer). Nach Verlassen der Funktion 
ist diese lokale Variable nicht mehr gültig. Es würde gehen, wenn du sie 
als static deklarierst. Das globale cbuffer ist dann allerdings gänzlich 
überflüssig. Und ob das überhaupt sinnvoll ist, hängt davon ab, für was 
das Ganze letztlich gut sein soll.

PS: Die Zeile "p_cbuffer = &cbuffer;" ist fehlerhaft. Mosert da der 
Compiler gar nicht wegen "incompatible pointer type"?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Warum definierst du cbuffer nicht einfach global?
Also "char cbuffer[50];" in irgendeiner C-Datei außerhalb einer 
Funktion.

Autor: josefk (nologin?) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso.

Malloc ist deshalb nicht sinnvoll, dachte ich, da der dort reservierte 
Speicher ja fragmentiert sein kann und ich mit meinem Pointer dort 
durchlaufen will. Wenn ich z.B. auf cbuffer[4] zeige und dann soetwas 
mache:
int adresse = &cbuffer[4];
//jetzt habe ich die adresse von cbuffer[4].
//ich will aber auf cbuffer[5] mittels Addition...
adresse +=8;
//-->Fehler?!
Das funktioniert nicht immer, oder? Bin verwirrt.
Das Beispiel  ist aus der Luft gegriffen. Es Sollte eigentlich mal ein 
Array aus Structs werden. Wollte das ganze aber nicht unnötig 
verkomplizieren.
Ich dachte eben, dass ich später mittels einfach Pointerarithmetik nicht 
mehr alle Teile meines Array finden werde, wenn ich den Speicher dafür 
mittels malloc() reserverie, oder?
Mit Indizes kann ich schon darauf zugreifen, aber ich bin später auch 
mal gezwungen direkt Adressen zu übergeben...

Als char cbuffer[50]; kann ich nicht einfach am anfang festelgen, da 50 
nicht fest ist. könnte je nach Konfiguration auch 60 oder was anderes 
sein...

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn Malloc wirklich fragmentiert wie sollte das dann gehen, du bekommt 
ja nur ein zeiger zurück. Hast also nur 1 Adresse und eine größe. Man 
hätte ja überhaupt keine Möglichkeit auf verschiende Fragmenge 
zuzugreifen.

bei char* p = malloc(100); darf man alles von p[0] - p[99] benutzten und 
das ist auch immer ein block.

Autor: josefk (nologin?) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso. Wenn ich dann also nicht mittels Indizes auf den von Malloc() 
reservierten Speicher zugreife, sonder meinen Pointer immer um 1 erhöhe, 
müßte ich jeden wert im Block treffen, oder?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist egal wie du zugreifst. Malloc liefert immer einen Pointer auf 
einen zusammenhängenden Block, oder eben einen Null-Pointer, wenn es 
keinen zusammenhängenden Block entsprechender Größe mehr gibt.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es gibt nicht wirklich "Indizes" beim zugriff auf speicher.

p[0] == *p
p[99] == *(p+99)

Autor: josefk (nologin?) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich also mit malloc speicher in einer Funktion reserviere und nicht 
mehr frei gebe, und den Rückgabewert von Malloc() auf meinen globalen 
Pointer gebe, dann kann ich von überall auf diesen Speicher zugreifen, 
oder?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich also mit malloc speicher in einer Funktion reserviere und nicht
> mehr frei gebe, und den Rückgabewert von Malloc() auf meinen globalen
> Pointer gebe, dann kann ich von überall auf diesen Speicher zugreifen,
> oder?

Das gleiche macht malloc doch, er reserviert speicher und gibt ihn 
zurück.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie man ein mit malloc angelegtes Array von Strukturen benutzt:
#include <stdio.h>
#include <stdlib.h>

struct vieldrin {
  double f;
  int i, j, k;
};

#define N 100

int main(void) {
  struct vieldrin *vdptr;
  //             Anzahl Elemente
  //             |   Größe eines Elements
  //             |   |
  //             V   V
  vdptr = malloc(N * sizeof (struct vieldrin));
  if(vdptr == NULL) 
    fprintf(stderr, "zu wenig Speicher\n");
  else {
    vdptr[0].f      = 1.2;
    // Folgende drei Zeilen tun exakt dasselbe:
    vdptr[99].i     = 123;
    (*(vdptr+99)).i = 123;
    (vdptr+99)->i   = 123;
    // ...
    free(vdptr);
  }
  return 0;
}

Natürlich steht es dir frei, vdptr global zu machen. Das Array steht
solange im gesamten Programm zur Verfügung, bis irgendwo free(vdptr)
aufgerufen wird.

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.