PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] warum coredump?



Prick
27-05-2003, 21:02
Hallo,

ich hab da mal eine kleine Frage bezüglich unten genannter Quelle:


...
char *ary[1024];
int i;

for(i=0; i<10;i++){
snprintf(ary[i], sizeof(ary), "a=%d", i);
printf("mein array: %s", ary[i]);
}
...

Wieso erhalte ich nach Ausführen des Programms einen Coredump?
Mach ich ein ary[i] = "test"; , dann funktioniert das Schreiben in den array, warum nicht mit snprintf(), bzw. was muss ich anders machen? Wäre nett, wenn man meine Zeilen verbessern könnte.

danke im Voraus,
h.d.

maceop
27-05-2003, 21:39
afaik wird dann ein segmentation fault ausgelöst wenn z.B. ein BufferOverflow auftritt. Vielleicht liege ich falsch , aber müsste es nicht

sizeof(ary) - 1

heissen ?

mfg
maceop

Prick
27-05-2003, 21:49
Danke für Deine Antwort,

leider hatte ich das bereits versucht, bringt keinen Erfolg.

tkortkamp
27-05-2003, 21:58
Hi!

Wenn du ein mehrdimensionales Array benutzt, dann musst du auch Speicher dafür reservieren. Also entweder beispielsweise so:


char ary[10][1024];

oder mit malloc.

c ya,
Tobias

Prick
27-05-2003, 22:24
Hi,

danke für Deine Antwort, auch an deine erste Variante hatte ich gedacht, allerdings weiß ich nicht, wie ich diese umsetzen kann. Zumindest nicht, wie das snprinft oder das printf am ende aussehen muss.
Wenn Du mir auch die Methode von malloc() erläutern könntest, wäre ich dir sehr dankbar. Ich weiß, was malloc macht, aber leider auch hier nicht, wie es auf das gegebene Beispiel anweden kann.

Danke im Voraus.

tkortkamp
27-05-2003, 23:29
Hi!



#include <stdio.h>
#include <malloc.h>

void fill(char ***array)
{
int i = 0;

*array = (char**) malloc(sizeof(char*) * 10);
for (i = 0; i < 10; i++)
{
(*array)[i] = (char*)malloc(sizeof(char) * 1024);

snprintf((*array)[i], 1024, "a=%i", i);

}
}

int main()
{

char **array;
int i = 0;

fill(&array);

for (i = 0; i < 10; i++)
{
printf("%s\n", array[i]);
/* Speicher wieder freigeben */
free(array[i]);
}
/* Speicher wieder freigeben */
free(array);

return 0;
}


Morgen kann ich dir alles etwas näher erklären, solltest du Fragen haben. Jetzt bin ich erstmal schlafen.

Gute Nacht,
Tobias

Prick
28-05-2003, 18:52
Hallo,

jetzt habe ich endlich Zeit, weitere Fragen zu stellen. :-)
Am besten ich analysieren Deinen Quelltext und schreibe, was ich weiß und was nicht.

#include <stdio.h> // ist klar :-)
#include <malloc.h>

void fill(char ***array) // warum drei sterne vor der Variablen? Reicht nicht einer?
{
int i = 0; // klar

*array = (char**) malloc(sizeof(char*) * 10); // das malloc ist verstanden, aber auch hier. Warum 2 Sterne beim char?
for (i = 0; i < 10; i++) // klar
{
(*array)[i] = (char*)malloc(sizeof(char) * 1024); // hier ist nur ein stern?

snprintf((*array)[i], 1024, "a=%i", i); // verstanden

}
}

int main()
{

char **array; // warum mit zwei deklariert?
int i = 0;

fill(&array); // warum an der Stelle eine adresse? Geht das in Verbindung mit malloc nur so?

for (i = 0; i < 10; i++) // klar
{
printf("%s\n", array[i]);
/* Speicher wieder freigeben */
free(array[i]); // klar
}
/* Speicher wieder freigeben */
free(array); // auch klar

return 0;
}


wenn Du mir das benatworten könntest, hättest Du mir enorm geholfen, Danke!

Gruß,
h.d.

tkortkamp
28-05-2003, 21:55
Hi!

Na dann leg ich mal los :)



void fill(char ***array) // warum drei sterne vor der Variablen? Reicht nicht einer?

Sagen wir mal du möchtest ein Integer als Pointer einer Funktion übergeben. Das machst du ja so:


void fill(int *integer)
{
//(...)
}

int main(int argc, char **argv)
{
int i = 1;

//(...)

//Wir übergeben hier der Funktion fill() i als Pointer
fill(&i);
}

Die beiden anderen Sterne sind bloss da weil es sich hier um ein char*-Array handelt, also ein * für die Zeichenkette (char*) und das andere um es als Array zu kennzeichnen. Einfacher zu verstehen wäre es evtl. wenn man ein neuen Typ definiert:


typdef char** char_array;

Dann könnte man


void fill(char_array *array)

schreiben.



char **array; // warum mit zwei deklariert?

Weil es sich um ein Array von char*-Pointern handelt. Ich hätte char* array[]; schreiben sollen, aber
darauf bin ich gestern abend nicht mehr gekommen ;-).



fill(&array); // warum an der Stelle eine adresse? Geht das in Verbindung mit malloc nur so?

Weil ich fill() einen Pointer zu unserem char* array[] gebe. Das hat mit malloc überhaupt nichts zu
tun. Das ist eine ganz normale Parameterübergabe.



*array = (char**)
malloc(sizeof(char*) * 10); // das malloc ist verstanden, aber auch hier. Warum 2 Sterne beim char?
for (i = 0; i < 10; i++) // klar
{
(*array)[i] = (char*)malloc(sizeof(char) * 1024); // hier ist nur ein stern?

Es handelt sich hier um ein Array von char*-Pointern (Zeichenketten). Das erste malloc reserviert
nun Speicher für das eigentlich Array von 10 char*-Pointern (deswegen auch sizeof(char*) * 10).
Schön und gut, jetzt hätten wir ein Array von char*-Pointern, um aber damit arbeiten zu können,
müssen diese auch irgendwo draufzeigen, deshalb reservieren wir mit dem 2. malloc für jedes Feld im Array genau 1024 Zeichen (also im Prinzip 10*1024-Zeichen)

So! ich hoffe, ich habe alles richtig und halbwegs verständlich erklärt. :)

c ya,
Tobias

Prick
28-05-2003, 22:37
Danke, hat mir sehr weitergeholfen.

Gruß,
h.d.

Prick
06-06-2003, 16:34
So, ist schon eine Weile her, aber vielleicht kannst Du, oder jemand anders mir eine weitere Frage beantworten, das was Du erklärt hast, habe ich denke ich verstanden.

Wie ist es denn, wenn die Anzahl der Zeilen des Arrays (im Beispiel 10) auch dynamisch ist ?
Wenn also immer mal eine Zeile dazu kommt, und man nicht weiß, wieviel es am Ende sind? Wie würde der Source dann aussehen? bzw. das Malloc -> *array = (char**) malloc(sizeof(char*) * 10); ?
Dieses malloc würde dann ja auch in der Schleife stehen ?!

Wäre um eine weitere Antwort sehr dankbar.

Grüße,
h.d.

tkortkamp
07-06-2003, 23:54
Hi!

So was macht man mit realloc. Guck dir am besten mal die man-Page zu realloc an (man 3 realloc).

Der Source müsste ungefähr so aussehen:


#include <stdio.h>
#include <malloc.h>

void init(char ***array)
{
/* Für ein erstes Element */
*array = (char**) malloc(sizeof(char*));
(*array)[0] = (char*)malloc(sizeof(char) * 1024);

snprintf((*array)[0], 1024, "a=0");
}


void modify(char ***array, int flag) /*flag=1: free, flag=0: alloc*/
{
static int oldsize = 0;
static int size = 1; /* Wir haben schon 1 Element */
int i;

switch(flag)
{
case 0:
oldsize = size;
size++;
*array = (char **)realloc(*array, sizeof(char*) * size);
for(i = oldsize; i < size; i++)
{
(*array)[i] = (char*)malloc(sizeof(char) * 1024);
snprintf((*array)[i], 1024, "a=%i", i);
}
break;
case 1:
for(i = 0; i < size; i++)
{
free((*array)[i]);
}
free(array);
break;
default:
break;
}
}




int main()
{

char **array;
int i = 0;

init(&array);

for (i = 0; i < 50; i++)
{
modify(&array, 0);
printf("%s\n", array[i]);
}

/* Speicher freigeben */
modify(&array, 1);
return 0;
}


HTH

c ya,
Tobias