PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : c++ Array Übergabe



Ramser
17-03-2008, 10:50
hi!

bin hier gerade echt am verzweifeln... trotz stundenlanger suche und probieren, komm ich nicht weiter...


Habe eine Funktion, die ein char[64]- array als Rückgabewert haben soll

main()
{
char data[64];
data = foo();
}

char* foo()
{
char data[64];
//fülle array
return data;
}


jetzt kommt: error C2440: '=': 'char *' kann nicht in 'char [64]' konvertiert werden.

Habe mittlerweile alles mögliche ausprobiert und mehrere (hauptsächlich schlechte) Tutorials durch... :(

BLUESCREEN3D
17-03-2008, 12:49
Das Problem an deiner Funktion foo() ist erstmal, dass das Array "data" eine lokale Variable ist und selbst wenn du dessen Adresse zurückgibst, hört es am Funktionsende auf zu existieren.
Um also einen Zeiger zurückgeben zu können, müsstest du einen Speicherbereich mit malloc() reservieren. Das ist aber nervig, weil den dann auch wieder freigeben musst.
Deshalb übergibt man üblicherweise der Funktion einfach die Adresse des bereits existierenden Arrays, damit es gefüllt werden kann:

void foo(char data[])
{
//array füllen
}

Aufruf: foo(data);
Allerdings kann die Funktion nicht prüfen, ob data wirklich 64 Einträge hat. Deshalb solltest du dir mal std::vector angucken. Dann könntest du auch eine normale Rückgabe benutzen.

PS: Benutz bitte hier im Forum das [code]-Tag.

Ramser
17-03-2008, 14:43
hi!

vielen Dank für deine Antwort :)


hatte die Funktion foo zu sehr gekürzt... das Problem mit dem "aufhören zu existieren" gabs da nicht :) . Einen Vektor zu nehmen lohnt sich da nicht, es sind immer genau 64 Arrayeinträge.

Habe jetzt foo so angepasst, dass ich das array gleich übergebe.


main()
{
char data[64];
foo(&(*data));
}

void foo(char data[64])
{
//fülle array
return;
}

naja so klappt es ersteinmal. Aber was hätte ich eigentlich in der ursprünglichen Version falsch? Stehe mit den Pointern ein wenig auf Kriegsfuss... und mich interessiert das jetzt :D

jan61
17-03-2008, 19:34
Moin,


...Habe jetzt foo so angepasst, dass ich das array gleich übergebe.


main()
{
char data[64];
foo(&(*data));
}

void foo(char data[64])
{
//fülle array
return;
}

Ganz schlechte Idee:

jan@jack:~/tmp/carray> cat carray.c
#include <stdio.h>

void foo(char data[64]) {
printf("size: %d\n", sizeof(data));
strcpy(data, "hallo welt");
}

int main(int argc, char **argv) {
char data[64];

foo(data);
printf("size: %d data: %s\n", sizeof(data), data);
return 0;
}

jan@jack:~/tmp/carray> ./carray
size: 4
size: 64 data: hallo welt
Du siehst das Problem? In foo kannst Du char-Array als Parameter definieren wie Du willst - es kommt trotzdem nur ein char-Pointer an, das sieht man an der sizeof-Ausgabe. Deklariere foo so, wie BLUESCREEN3D schreibt, dann denkst Du nicht irrtümlicherweise, dass Du in Funktionen die Array-Größe eines Arguments kennen würdest. Du musst also absichern, dass Du nicht über die Grenzen des Array hinausschreibst, z. B. indem Du per #define eine Größe definierst, oder indem Du die Größe mitgibst:

jan@jack:~/tmp/carray> cat carray.c
#include <stdio.h>

#define BUFSIZE 64

void foo1(char *data) {
printf("size: %d BUFSIZE %d\n", sizeof(data), BUFSIZE);
strncpy(data, "hallo welt", BUFSIZE - 1);
}

void foo2(char *data, size_t max) {
printf("size: %d max: %d\n", sizeof(data), max);
strncpy(data, "hallo welt", max - 1);
}

int main(int argc, char **argv) {
char data[BUFSIZE];

foo1(data);
foo2(data, sizeof(data));
printf("size: %d data: %s\n", sizeof(data), data);
return 0;
}

jan@jack:~/tmp/carray> make carray
cc carray.c -o carray
jan@jack:~/tmp/carray> ./carray
size: 4 BUFSIZE 64
size: 4 max: 64
size: 64 data: hallo welt
Warum Deine 1. Variante nicht funktioniert? Dein foo gibt einen char-Pointer zurück, nämlich die Adresse der lokalen Variablen data, die nebenbei gesagt, wie BLUESCREEN3D schon schrieb, am Ende von foo zu existieren aufgehört hat. In main hast Du aber data als char-Array deklariert, das hat eine Adresse, die Du nicht einfach überschreiben kannst.

Jan

P.S.: Der Aufruf foo(&(*data)) ist doppelt gemoppelt. *data ist der Inhalt der ersten Stelle von data, gleichbedeutend zu data[0], davon holst Du Dir die Adresse. foo(data) ist identisch dazu.

BLUESCREEN3D
17-03-2008, 19:38
foo(&(*data));
Hier kannst du & und * weglassen - die heben sich gegenseitig auf.


Aber was hätte ich eigentlich in der ursprünglichen Version falsch?
Was falsch war, ist diese Zuweisung: data = foo();
Du hast angegeben, dass foo() einen char-Pointer zurückgeben soll. "data" ist aber ein Array.

edit: Zu spät ...

Ramser
18-03-2008, 20:12
hey vielen Dank!

jetzt ist mir einiges klar geworden :)