VS - C Problem

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

VS - C Problem
Kann mir jemand bei folgendem (einfachen :wand: ) Problem helfen:

Die Methode writeArray() ist wie folgt definiert:

bool	readArray(int len, int8_t *array[]);

Um sie aufzurufen benutze ich:

int8_t a[] = {'h', 'e', 'l', 'l', 'o', '\0'};

MessageBuffer	b(6 * 4);
Message	m(&b);

m.writeArray(6, a);

for (int i = 0; i < 6; i ++)
	a[i] = '@';

m.readArray(6, &a);

Leider gibt es in der letzten Zeile ein Problem, der Compiler sagt:

cannot convert int8_t *[6] into int8_t **

Wie muss ich a an readArray() korrekt übergeben?


Nur mal interessehalber, warum arbeitest du mit Zeigern auf arrays? Was spricht dagegeben sowas wie readData(int len, void * data) zu machen? C kann die Grenzen eines Arrays eh nicht erkennen und a ist eh nur ein Zeiger auf den Beginn des Arrays.


Wieso füllst du den Array mit @s auf? (btw dafür würde ich memset empfehlen)

Wieso schreibst du einmal
m.writeArray(6, a);
ein andermal
m.readArray(6, &a);

Bekommt writeArray andere Parameter als readArray?

Schlussendlich ist int8_t *array[] ein Array von int8_t Pointern und nicht Werten. (ganz im Gegensatz zu int8_t a[])
Deswegen funktioniert auch die Conversion nicht.

Ich tippe mal darauf, dass die Funktionsdeklaration falsch ist.


Das stimmt so nicht - er uebergibt ja die Adresse des Arrays. Ausserdem muss int8_t *array kein Array von Pointern sein, sondern kann auch ein Pointer auf ein Array sein - intern auf jeden Fall ein int8_t **array. Deshalb ist keine Konversion noetig und ich verstehe die Fehlermeldung nicht.

Der Aufruf passt auch zur Deklaration - aber du musst dir natuerlich bewusst sein, was dir da uebergeben wird. Ob das so, wie es da steht, sinnvoll ist, ist die andere Frage (siehe Eriks Post).


Hallo,

ich habe etwas eilig gepostet. Aber dennoch besteht für mich noch klärungsbedarf.

Die Frage ist doch, wie diese Adresse schlußendlich interpretiert wird (auf was sie zeigt).

Entweder, oder? Was von beidem denn nun - ist es wirklich das gleiche?

'Pointer auf einen Array:
zeiger auf → Array-Adresse (macht keinen Sinn, man kann gleich die Adresse selbst übergeben; weswegen ja auch wenn man nur bla übergibt, schon die Adresse übergeben wird - der Array wird ja nicht auf den Stack gehievt!)

Worin würde denn der Sinn eines Pointers auf einen einzelnen Array bestehen?!

Array von Pointern:
[0] zeigt auf → Adresse char etc. nr. 1
[1] zeigt auf → Adresse char etc. nr. 2
[2] zeigt auf → Adresse char etc. nr. 3
etc.

Es ist schon richtig, dass ein Array intern nichts anderes ist als ein Pointer. Allerdings geht es ja darum, wie es interpretiert wird, bzw. wie man mit dieser Adresse umgeht, und ich denke deswegen beschwert sich auch der Compiler.
Die Funktion erwartet nämlich die Adresse, in der ein weiterer Zeiger steht (imho). Das würde eben bei einem Array von Pointern Sinn machen.

cu
Ford Prefect


Hi,

Ja.

Ja. Ich hatte ja auch gesagt, ueber die Sinnigkeit laesst sich diskutieren.

Das haengt von der Funktion ab - die wir zu dem Zeitpunkt nicht kennen. Sie kann die Argumente interpretieren, wie sie will - aber das kann der Compiler nicht wissen, deswegen verstehe ich das in dem Kontext auch nicht.

@Mathias: Poste doch bitte mal die ominoese Funktion :].

Gruesse,
-Steppenwolf


Benutze jetzt int8_t *data, funktioniert einwandfrei

bool Message::readArray(int len, int8_t *data)
{
	for (int i = 0; i < len; i ++)
		if (read(&data[i]) == false) return false;

	return true;
}

Also, wie man sieht, erwartet die Funktion, dass ihr ein (Zeiger auf einen) Array übergeben wird, und nicht ein Pointer auf die Adresse, auf der ein Pointer auf den Array liegt… (was unsinnig ist), aber auch nicht, einen Pointer auf die Adresse, auf der ein Pointer liegt, der das erste Element eines Pointer arrays ist (was meiner Meinung nach die entspr. Interpretation der Parameter-Deklaration darstellt).

Dass der Compiler sich beschwert, empfinde ich für mehr als logisch, denn er muss schließlich davon ausgehen, dass eine Funktion, die die Adresse eines Pointers übergeben bekommen will, die Adresse eines int8_t übergeben bekommt.
Wenn man diese Typprüfung auch bei Pointern umgehen will, muss man nunmal entspr. casten (z.B. über void Pointer).

cu
Ford Prefect


@Matthias: Hast du das jetzt veraendert, oder?

@Ford: Wenn das zur Compile-Zeit wirklich so aussah wie jetzt, dann ist es klar, dass gemeckert wird. Aber wenn ich Matthias richtig verstehe, sah es vorher anders aus.

Aber ist ja auch egal, hauptsache, es funktioniert jetzt :].


Also tut mir leid, aber ich habe auch bei anderen Leuten, die sich damit auskennen sollten, nochmal nachgefragt und wir sind gemeinschaftlich zu dem Ergebnis gekommen, dass das, was ich geschrieben habe, so schon richtig ist.

Und das bezieht sich natürlich auf den Originalpost.

Vllt. sehen wir uns ja demnächst mal wieder in RL, dann können wir das ja nochmal zusammen nachvollziehen.


Ja, vorher war’s int8_t *data