Forum: Compiler & IDEs zusammhängendes Speicherfeld reservieren


von josefk (nologin?) (Gast)


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:
1
extern char cbuffer[];
2
extern char *p_cbuffer;
Dann definiere ich diese Werte in meiner main.c und in einer 
Unterfunktion
1
//main.c
2
char *p_cbuffer = 0;
3
//Funktion in einer anderen .c, die von main.c aufgerufen wird
4
char cbuffer[50];
5
p_cbuffer = &cbuffer;

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

von Peter (Gast)


Lesenswert?

warum ist malloc() keine lösung?

von Stefan E. (sternst)


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"?

1
extern char cbuffer[];
2
extern char *p_cbuffer;
> Dann definiere ich diese Werte in meiner main.c und in einer
> Unterfunktion
1
//main.c
2
char *p_cbuffer = 0;
3
//Funktion in einer anderen .c, die von main.c aufgerufen wird
4
char cbuffer[50];
5
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"?

von Stefan E. (sternst)


Lesenswert?

Nachtrag:

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

von josefk (nologin?) (Gast)


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:
1
int adresse = &cbuffer[4];
2
//jetzt habe ich die adresse von cbuffer[4].
3
//ich will aber auf cbuffer[5] mittels Addition...
4
adresse +=8;
5
//-->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...

von Peter (Gast)


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.

von josefk (nologin?) (Gast)


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?

von Stefan E. (sternst)


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.

von Peter (Gast)


Lesenswert?

es gibt nicht wirklich "Indizes" beim zugriff auf speicher.

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

von josefk (nologin?) (Gast)


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?

von Stefan E. (sternst)


Lesenswert?

Ja.

von Peter (Gast)


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.

von yalu (Gast)


Lesenswert?

Wie man ein mit malloc angelegtes Array von Strukturen benutzt:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
struct vieldrin {
5
  double f;
6
  int i, j, k;
7
};
8
9
#define N 100
10
11
int main(void) {
12
  struct vieldrin *vdptr;
13
  //             Anzahl Elemente
14
  //             |   Größe eines Elements
15
  //             |   |
16
  //             V   V
17
  vdptr = malloc(N * sizeof (struct vieldrin));
18
  if(vdptr == NULL) 
19
    fprintf(stderr, "zu wenig Speicher\n");
20
  else {
21
    vdptr[0].f      = 1.2;
22
    // Folgende drei Zeilen tun exakt dasselbe:
23
    vdptr[99].i     = 123;
24
    (*(vdptr+99)).i = 123;
25
    (vdptr+99)->i   = 123;
26
    // ...
27
    free(vdptr);
28
  }
29
  return 0;
30
}

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.