[C] Pointer frage

Schattenfänger

Lt. Junior Grade
Registriert
Nov. 2010
Beiträge
273
Hallo, ich dachte eigentlich Pointer verstanden zu haben aber irgendwie komme ich bei diesem Problem nicht weiter.

Code:
main{
int[] age={1,2,3,4,5};

avg(age);
}

void avg(int[] arr){
int len=sizeof(arr)/sizeof(arr[0]);
}

Wenn ich das ausführe erhalte ich wenn ich die Länge in der Methode berechne einen falschen Wert.
Wenn ich die gleiche Berechnung in der main ausführe, so bekomme ich genau die Anzahl der Elemente des Arrays.

Ich weiß, dass Arrays nichts anderes sind als Pointer auf das erste Element, bzw so in die Methode übergeben wird.
Ich dachte das es etwas damit zu tun haben könnte, aber theoretisch muss doch auch das aufs gleiche rauskommen.

Wenn ich mir das mal so ansehe:
arr= 0x10000;
avg(0x10000){
len=0x10020/0x10000
}

oder etwa nicht?
 
Der Zeiger enthält keine Information darüber, wie groß der Speicherbereich ist, auf den er zeigt.
 
Wie adsfman schon sagte, wenn du nur einen Pointer hast, gibt es keinen Weg, (nur anhand dieses Pointers) zu bestimmen, wie viele Elemente das referenzierte Array hat. Mit dem Array selbst funktioniert das schon. Wenn du allerdings dein Array an eine Funktion übergibst, übergibst du streng genommen eigentlich nicht das Array selbst sondern lediglich einen Zeiger auf sein erstes Element. Man spricht hier vom Array-Zerfall (englisch array decay oder pointer decay), weil das Array beim Übergeben quasi zu einem Pointer "zerfällt", und ein Pointer selbst enthält natürlich keinerlei Information über das Array, auf das er zeigt .... abgesehen von der Adresse selbst natürlich.
 
Als Ergänzung - das "Programm" müsste ungefähr so aussehen:

Code:
void avg(int arr[], size_t size){
    printf("%lu\n", size / sizeof(int));
}

int main(void)
{
    int age[] = {1,2,3,4,5};     
    avg(age, sizeof(age));
}
 
Ahh entschuldigung, sehe gerade erst, dass das Programm wirklich nicht sehr schön dargestellt ist.

Also es ist so wie ichs mir schon dachte.

Läuft es dann auf das hinaus:
Ich habe eben meinen Funktionsaufruf. Der Compiler "generiert" den Stack und erstellt einen Pointer auf das übergebene Array?
Und wenn ich dann sizeof Abfrage erhalte ich die Größe vom Pointer, welcher nach wie vor vom Typ char ist und damit 1 Byte lange ist?
Und die Value davon ist dann halt 0x100000.

Aber wie macht es dann das Array?
Wenn ich jetzt in der main die Größe davon abfrage erhalte ich doch die korekte Antwort, obwohl es doch auch nur auf den ersten Eintrag zeigt. Oder wird das vom Compiler schon gesondert behandelt?
 
Schattenfänger schrieb:
Ahh entschuldigung, sehe gerade erst, dass das Programm wirklich nicht sehr schön dargestellt ist.

Also es ist so wie ichs mir schon dachte.

Läuft es dann auf das hinaus:
Ich habe eben meinen Funktionsaufruf. Der Compiler "generiert" den Stack und erstellt einen Pointer auf das übergebene Array?
Und wenn ich dann sizeof Abfrage erhalte ich die Größe vom Pointer, welcher nach wie vor vom Typ char ist und damit 1 Byte lange ist?
Und die Value davon ist dann halt 0x100000.

Aber wie macht es dann das Array?
Wenn ich jetzt in der main die Größe davon abfrage erhalte ich doch die korekte Antwort, obwohl es doch auch nur auf den ersten Eintrag zeigt. Oder wird das vom Compiler schon gesondert behandelt?



Zu dem rot markierten Teil. Nein, das Ding ist vom Typ char*, also Zeiger auf char, und ist damit so groß, wie ein Zeiger auf deinem System eben ist (wahrscheinlich 32 oder 64 Bit).

Nun zum blau markierten Teil. Nun, das ist eben der Unterschied zwischen einem Array und einem Pointer auf ein Array. Die sind eben nämlich NICHT das gleiche, und der Compiler weiß das auch ... deshalb ist es ihm ein Leichtes, die Größe eines Arrays zu bestimmen ... die wird ja schließlich beim Erstellen des Arrays angegeben. Nur muß man dem sizeof-Operator dann eben auch ein Array geben. Mit einem bereits "zerfallenen" Zeiger kriegst du dann nur noch die Größe des Zeigers, und die nutzt dir, wie du ja schon erkannt hast, herzlich wenig.
 
Wenn ich jetzt in der main die Größe davon abfrage erhalte ich doch die korekte Antwort, obwohl es doch auch nur auf den ersten Eintrag zeigt. Oder wird das vom Compiler schon gesondert behandelt?

Code:
#include <stdlib.h>

int nimmarray(char arr[]) {
    return sizeof(arr) / sizeof(char);
}

int main(void) {
    char peter[5] = { 'p', 'e', 't', 'e', 'r' };
    char olaf[4] = { 'o', 'l', 'a', 'f' };

    int peterret, olafret;

    peterret = nimmarray(peter);
    olafret = nimmarray(olaf);

    return EXIT_SUCCESS;
}

In main() sind peter und olaf zwei verschiedene Objekte, für die der sizeof-Operator eine Eindeutige Antwort geben kann. nimmarray() weiß nur, dass es irgendein Array übergeben bekommt und hat keinerlei Information über dessen Länge. nimmarray() kann nicht gleichzeitig 4 (für olaf) und 5 (für peter) zurückgeben, wenn beide Male der selbe Code ausgeführt wird. Das wäre ein Widerspruch.
 
Zurück
Oben