Forum: Compiler & IDEs Call by reference mit Array - wieso klappt das nicht


von Nico B. (vegetico)


Lesenswert?

Moin...
Als Vorwarnung - ich hantiere nicht oft mit C... Daher mag die Frage ein 
wenig dämlich sein...
Folgendes schlägt bei mir immer fehl - und ich weiß ehrlich gesagt nicht 
wieso.

Funktionsaufruf in main()
1
resetData(&data);

Funktion selbst:
1
void resetData(char *someData[])
2
{
3
  size_t dataLength = sizeof(*someData) / sizeof(char);
4
  for (int i = 0; i<dataLength; i++)
5
  {
6
    *someData[i] = 0;
7
  }
8
}

bzw. (weil ich mir beim dereferenzieren nie sicher bin)
1
void resetData(char *someData[])
2
{
3
  size_t dataLength = sizeof(*someData) / sizeof(char);
4
  for (int i = 0; i<dataLength; i++)
5
  {
6
    someData[i] = 0;
7
  }
8
}


Selbst wenn ich dataLength fest auf einen Wert setze ist 'someData' im 
Debugger nicht 'sichtbar'. Sprich Data nicht nicht verändert bzw. im 
Kontext von 'resetData' nicht sichtbar...
Warum geht das nicht???

Danke schonmal

Gruß
Nico

von Sebastian R. (Gast)


Lesenswert?

Hi!

Nehme mal an, dass du irgendwo in main oder global data wie folgt 
definierst:
char data[5];

Der Aufruf "resetData(&data);" macht dann keinen Sinn, da data ohne [] 
schon ein Zeiger ist und du den Adress-Operator nicht mehr brauchst.
Funktionieren würden: resetData(data); oder resetData(&data[0]);.

Der zweite Code für die Funktion ist besser. (* und [x] sind doppelt 
gemoppelt).
ABER: "void resetData(char *someData)" ohne "[]" (oder ohne Stern geht 
auch), wäre auch doppelt.

Grüße

Sebastian

von *char (Gast)


Lesenswert?

zeig mal die Definition von data

von Stefan E. (sternst)


Lesenswert?

Sebastian R. schrieb:
> Der zweite Code für die Funktion ist besser. (* und [x] sind doppelt
> gemoppelt).
> ABER: "void resetData(char *someData)" ohne "[]" (oder ohne Stern geht
> auch), wäre auch doppelt.

Ne, das ist nicht irgendwie doppelt gemoppelt, sondern schlicht falsch. 
"char *someData[]" ist ein Array aus Pointern auf char.

Das nächste Problem ist das hier:
1
size_t dataLength = sizeof(*someData) / sizeof(char);
Du hast keine Chance innerhalb der Funktion über sizeof an die Anzahl 
der Elemente des Arrays zu kommen. Entweder du packst eine eindeutige 
Ende-Kennung an das Ende des Arrays, oder du übergibst die Anzahl als 
zusätzlichen Parameter an die Funktion.

von Rolf Magnus (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Sebastian R. schrieb:
>> Der zweite Code für die Funktion ist besser. (* und [x] sind doppelt
>> gemoppelt).
>> ABER: "void resetData(char *someData)" ohne "[]" (oder ohne Stern geht
>> auch), wäre auch doppelt.
>
> Ne, das ist nicht irgendwie doppelt gemoppelt, sondern schlicht falsch.
> "char *someData[]" ist ein Array aus Pointern auf char.

Nicht ganz. Wenn es als Paramtertyp angegeben wird, ist es ein Zeiger 
auf einen Zeiger auf char.

> Das nächste Problem ist das hier:
> size_t dataLength = sizeof(*someData) / sizeof(char);
> Du hast keine Chance innerhalb der Funktion über sizeof an die Anzahl
> der Elemente des Arrays zu kommen.

Richtig. *someData ist vom Typ "Zeiger auf char", sizeof(char) ist per 
Definition 1. Also wird in dataLength immer die Größe eines Zeigers 
stehen.

von Nico B. (vegetico)


Lesenswert?

OK, danke...
Die Definition von data is in main und sieht so aus
1
static unsigned char data[10];

Das mit dem SizeOf hatte ich von z.B. hier gesehen: 
http://openbook.galileocomputing.de/c_von_a_bis_z/011_c_arrays_004.htm#mj3f5445113443dfa117781b465336c610
Als generelle Frage - ein Array ist ja immer 'nur' ein Zeiger auf das 
jeweilige Element. Wieso funktioniert das in dem Galileo Beispiel??? Das 
müßte doch eigentlich das Gleiche sein

von DirkB (Gast)


Lesenswert?

Weil in dem Beispiel die Definition von data und die Abfrage mit 
sizeof() innerhalb der selben Funktion (hier main()) stattfindet.

In main ist data ein Feld und kein Zeiger.

Wenn du in dem Buch dann mal weiterliest (gleich das nächste Kapitel) 
steht da auch, dass das so nicht funktioniert.


Ein Zeiger braucht Speicher für die Daten auf die er zeigt und für sich 
selber (die Speichserstelle wo die Adresse drin steht).
Das Array braucht nur Speicher für die Daten. Den Rest macht der 
Compiler beim compilieren.

von ET-Tutorials (Gast)


Lesenswert?

Hallo Nico,
vielleicht hilft mein Video zum Thema Pointer und Arrays
http://et-tutorials.de/3441/pointer-und-arrays/

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nico B. schrieb:
> OK, danke...
> Die Definition von data is in main und sieht so aus
1
> static unsigned char data[10];

Sowas warnt doch schon der Compiler an (bei Aufruf der Funktion) ...

Warnungen zur Compilezeit zu korrigieren ist immer einfacher, als Fehler 
zur Laufzeut zu finden und beheben!

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.