PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Memory allocation & struct in C



pfrei
10-06-2005, 11:09
Hallo

Ich möchte eine dynam. Speicherzuweisung in C vornehmen. Zuerst hatte ich folgenden statischen Code, der mir immer einen buffer overflow machte, wenn es mehr als 5000 "respnotfound"-entries gab:

struct response_url { char respurl[MAXURL]; };
struct response_url respnotfound[5000]; Jetzt habe ich folgendes gemacht:

struct response_url { char respurl[MAXURL]; };
struct* response_url respnotfound = new struct[5000]; Aber das gibt einen "parse error before *"...

Funktioniert mein Code denn nicht in C? Kann mir jemand helfen, vielleicht mit einem Beispielcode mit "struct"?

Vielen Dank!
Patrick

Boron
10-06-2005, 11:31
1. Wenn du das Schlüsselwort "new" verwendest, dann ist es C++. New gibt es nicht in C.

2. Wenn du unbedingt C verwenden willst, dann nutze "malloc(...)" um Speicher anzufordern und free(...) um ihn freizugeben.

3.
#define MAXURL 500

typedef struct responseUrl
{
char respurl[MAXURL];
} responseUrl;

int main()
{
responseUrl* respnotfound = new responseUrl[5000];

delete[] respnotfound;
return 0;
}Mein C++ Compiler sagt, dass das so gut ist.
Du hattest nur "new struct" da stehen. Wenn dir das mit dem typedef nicht gefällt, dann versuche mal "new struct repsonseUrl".

pfrei
10-06-2005, 19:51
Hi. Ich muss C verwenden. Wäre dann folgender Code korrekt?
struct response_url { char respurl[MAXURL]; };
struct response_url * respnotfound;
respnotfound = (struct response_url *) calloc (5000, sizeof(struct response_url));Und später könnte ich dann den Array in etwa folgendermassen füllen?

if (log_rec.resp_code=='404') {
strncpy(respnotfound[y].respurl,log_rec.url,strlen(log_rec.url));
y+=1;
}

Detrius
10-06-2005, 22:03
Du reservierst so aber immer noch Speicherplatz für 5000 Elemente des structs. Damit gibt es die gleichen buffer-overflows wie vorher auch. ;)

Eine Möglichkeit wäre mit realloc zu arbeiten, falls mehr Elemente benötigt werden oder z.B. eine verkettete Liste zu verwenden. In jedem Fall musst du selbst dafür Sorge tragen, dass der Speicherplatz mit dem Du arbeitest auch immer sicher vorher reserviert wurde.

pfrei
11-06-2005, 11:49
Habe jetzt folgenden Code zum Definieren der Daten:
struct response_url { char respurl[MAXURL]; };
struct response_url * respnotfound;respnotfound = (struct response_url *) calloc (5000, sizeof(struct response_url));

Zum Einlesen habe ich Folgendes:

if (log_rec.resp_code==RC_NOTFOUND) {
strncpy(respnotfound[y].respurl,log_rec.url, MAXURL-1);
//respnotfound[y].respurl[MAXURL-1] = 0;
y+=1;
}
Obiges funktioniert wie gewünscht. Wie kann ich denn herausfinden, wieviele respnotfound[y]'s insges. mit calloc alloziiert wurden? Ich muss das wissen, denn ich habe ja den Speicher mit realloc zu vergrössern, sobald er knapp wird. Z.B. wenn ich schon 4900 Wert aufgebraucht habe, möchte ich zusätzlich 5000 Werte reservieren:
if (y>=z) {
// realloc memory
// z holds the totally allocated values (5000)
// y holds the currently used values (i.e. 4900)
}
else {
// continue to fill-up the array
}

Thomas Engelke
14-06-2005, 07:50
Hallo!

Warum nicht verkettete Listen nutzen? Muß es denn der Speicher auf einem Haufen sein oder darf verteilt werden? Das Problem kann doch ggf. sein, daß (m/c)alloc es nicht schaffen, dir 45MB am Stück zu reservieren. Jedoch lassen sich x mal 20 Byte problemlos reservieren, wobei die Lage dann natürlich dem System überlassen wäre. Mit dieser Methode würdest du den Speicher bis zum letzten Byte ausnutzen können.

Achja: Herausfinden, wieviel Speicher bereits allokiert ist, läßt sich nicht so einfach und wird auch nicht empfohlen. Lieber merke man sich, wieviel man selbst allokiert hat, anstatt die im Hintergrund durchaus existenten Datenstrukturen, welche von (m/c)alloc genutzt werden, zu fragen, da dieses Verhalten plattform- und ggf. sogar compilerabhängig ist.

TME

anda_skoa
14-06-2005, 11:59
Wie kann ich denn herausfinden, wieviele respnotfound[y]'s insges. mit calloc alloziiert wurden?

5000
Hast du ja so angefordert

Ciao,
_