Forum: PC-Programmierung C: sizeof (zeigerinhalt)


von Jan S. (Gast)


Lesenswert?

Hallo,
habe eine Frage zu C.

Ich initialisiere ein int array[3] und verwende darauf sizeof(array).
Dabei erhalte ich 12 (= 3*4bit) was Sinn macht.

Nun übergebe ich den Pointer data an eine Funktion und will
intern wieder diese 12 bestimmen.(zur Fehlerkontrolle)
allerdings erhalte ich sowohl bei sizeof(data) oder sizeof(*data) = 4.

Wie komm ich an die 12 ran?

Gruß
Jan

von tuppes (Gast)


Lesenswert?

Gar nicht. Bei der Übergabe an die Funktion geht die Information über 
die Arraygröße verloren. Es geht nur über einen zusätzlichen formalen 
Parameter:
1
void function (
2
    int * data    // Datenfeld
3
    , int length  // Anzahl Elemente im Datenfeld
4
    )
5
{
6
    int i;
7
    for (i = 0; i < length; i++)
8
    {
9
        // do something with data[i]
10
    }
11
}
12
13
int somedata[3];
14
15
int main (void)
16
{
17
    function (
18
        somedata
19
        , sizeof (somedata) / sizeof (*somedata)  // das hier liefert 3
20
    );
21
}

von Ralf (Gast)


Lesenswert?

> Ich initialisiere ein int array[3]...
> Dabei erhalte ich 12 (= 3*4bit) was Sinn macht.
Macht keinen Sinn. Ein int ist in .NET 32-Bit, und auf nem "normalen" 
System 16-Bit. Daher vermute ich, dass du .NET programmierst, was dann 
korrekt ist:
3x 32-Bit = 3x 4 Byte = 12

> Nun übergebe ich den Pointer data an eine Funktion und will
> intern wieder diese 12 bestimmen.(zur Fehlerkontrolle)
> allerdings erhalte ich sowohl bei sizeof(data) oder sizeof(*data) = 4.
Zeig doch mal, WIE du übergibst.

Ralf

von Peter (Gast)


Lesenswert?

Ralf schrieb:
> Macht keinen Sinn. Ein int ist in .NET 32-Bit, und auf nem "normalen"
> System 16-Bit.

also bei mir ist ein int auch 32bit unter c,c++.

von Jan S. (Gast)


Lesenswert?

Oh ja,
du hast recht es sind 3*4 Byte.

übergeben tue ich so: (also die Funktionsdefinition)
function(WORD *data)

prinzipiell will ich genau das tun, was tuppes implementiert hat.
Folglich scheint das nich zugehen ohne, dass ich die Länge übergebe.

von Karl H. (kbuchegg)


Lesenswert?

Jan S. schrieb:

> Folglich scheint das nich zugehen ohne, dass ich die Länge übergebe.

Richtig.
Und webnn du dir die Funktionssignatur ansiehst

function(WORD *data)


dann steht da auch warum. Die Funktion erhält nur noch einen Pointer. 
Die weiß nichts von einem Array.

von Jan S. (Gast)


Lesenswert?

Ja das dacht ich mir schon.
Hatte gehofft, dass es doch noch ne möglichkeit gibt.

von Philipp B. (philipp_burch)


Lesenswert?

Noch ein genereller Hinweis zu sizeof(): Dieser Operator wird bereits 
zum Kompilierzeitpunkt ausgewertet. Daher wirst du den niemals zur 
Fehlerkontrolle einsetzen können. Arrays musst du in C fast immer mit 
einer Längenangabe ausstatten, sonst ist diese Information verloren. Die 
Ausnahme sind Strings (char[]), die definitionsgemäss per Nullbyte 
abgeschlossen werden. Das lässt sich natürlich auch für andere Arrays 
anwenden, ist aber eher unüblich.

Gruss,
Philipp

von Ralf (Gast)


Lesenswert?

>> Macht keinen Sinn. Ein int ist in .NET 32-Bit, und auf nem "normalen"
>> System 16-Bit.
> also bei mir ist ein int auch 32bit unter c,c++.
Ähm... Okay, sorry, wieder was gelernt. Kann sein, dass ich bei der 
Antwort entweder noch in Uralt-16Bit-PC-Zeiten war, oder 
(wahrscheinlicher) bei meinem C-Compiler für Microcontroller :)

Ralf

von Sven P. (Gast)


Lesenswert?

Gibt mehrere Möglichkeiten.

Wenn der Vektor immer gleichlang ist:
1
void funktion(int vektor[10]);

Wenn er variabel ist, geht mit C99:
1
void funktion(size_t laenge, int vektor[laenge]);

von Rolf Magnus (Gast)


Lesenswert?

Sven P. schrieb:
> Gibt mehrere Möglichkeiten.
>
> Wenn der Vektor immer gleichlang ist:
1
void funktion(int vektor[10]);

Das bringt gar nichts. Die 10 wird ignoriert, also ist das das gleiche 
wie
1
void funktion(int vektor[]);
was wiederum das gleiche ist wie:
1
void funktion(int* vektor);

Die einzige Möglichkeit wäre, einen Zeiger auf das Array zu übergeben:
1
void funktion(int (*vektor)[10]);

Dann bekommt man innerhalb der Funktion mit:
1
groesse = sizeof *vektor;
die Größe zurück.

von Sven P. (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Sven P. schrieb:
>> Gibt mehrere Möglichkeiten.
>>
>> Wenn der Vektor immer gleichlang ist:
>
1
> void funktion(int vektor[10]);
2
>
>
> Das bringt gar nichts. Die 10 wird ignoriert, also ist das das gleiche
> wie [...]

War so auch nicht gemeint. War eher so gemeint, dass man Länge 10 
annimmt und der Compiler im Zweifelsfall meckert. Verlangt natürlich 
nach etwas Disziplin.

von Rolf Magnus (Gast)


Lesenswert?

Sven P. schrieb:
> War so auch nicht gemeint. War eher so gemeint, dass man Länge 10
> annimmt und der Compiler im Zweifelsfall meckert. Verlangt natürlich
> nach etwas Disziplin.

Gibt es Compiler, die da meckern?

von Sven P. (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Sven P. schrieb:
>> War so auch nicht gemeint. War eher so gemeint, dass man Länge 10
>> annimmt und der Compiler im Zweifelsfall meckert. Verlangt natürlich
>> nach etwas Disziplin.
>
> Gibt es Compiler, die da meckern?

Mir ist keiner bekannt, deshalb ja die Disziplin :-)
Ne, sollte man vermutlich eher als Konvention verstehen, die Sache 
lesbar zu machen. Natürlich ginge auch ein einfacher Zeiger (int *), 
aber dann sieht man nicht mehr auf den ersten Blick die geforderte 
(Mindest-)Länge.

von Εrnst B. (ernst)


Lesenswert?

in C++ könnte man die Array-Länge als Template-Parameter vom Compiler 
automatisch einfüllen lassen, mit Konstrukten wie:
1
  namespace {
2
    template<typename text>
3
    class something_i {};
4
5
    template<int len>
6
    class something_i<char[len]> {
7
    public:
8
      static void do_something(const char op[len]) {
9
         for(int i=0; i<len; ++i) {...}
10
      }
11
    };
12
  }
13
  template<typename text>
14
  void do_something(const text & op) {
15
    something_i<text>::do_something(op);
16
  }
17
18
  ....
19
20
  do_something("Hallo Welt");
Würde in den Beispiel ein strlen einsparen, und trotzdem mit "\000" 
innerhalb der String-Konstante funktionieren.

Aber wenn man eh C++ nimmt, geht das alles sowieso viel besser mit 
std::vector, std::string &co.

von Karl H. (kbuchegg)


Lesenswert?

Sven P. schrieb:
> Rolf Magnus schrieb:
>> Sven P. schrieb:
>>> War so auch nicht gemeint. War eher so gemeint, dass man Länge 10
>>> annimmt und der Compiler im Zweifelsfall meckert. Verlangt natürlich
>>> nach etwas Disziplin.
>>
>> Gibt es Compiler, die da meckern?
>
> Mir ist keiner bekannt, deshalb ja die Disziplin :-)

Und genau aus dem Grund halt ich diese [] Schreibweise in Argumentlisten 
für problematisch: Sie suggeriert etwas, was einfach nicht stimmt.

von Sven P. (Gast)


Lesenswert?

So kann man das auch sehen. Aber Makros suggerieren auch etwas, das 
nicht ist.

Katze -> Schwanz :-}

Die Schreibweise mit [] im Prototyp hat hingegen doch einen Sinn. Dann 
nämlich, wenn die Vektorlängen eine Rolle spielen, etwa bei 
mehrdimensionalen Vektoren. Dann erspart man sich Zeigerrechnung.

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.