www.mikrocontroller.net

Forum: PC-Programmierung C: sizeof (zeigerinhalt)


Autor: Jan S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void function (
    int * data    // Datenfeld
    , int length  // Anzahl Elemente im Datenfeld
    )
{
    int i;
    for (i = 0; i < length; i++)
    {
        // do something with data[i]
    }
}

int somedata[3];

int main (void)
{
    function (
        somedata
        , sizeof (somedata) / sizeof (*somedata)  // das hier liefert 3
    );
}

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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++.

Autor: Jan S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jan S. (Gast)
Datum:

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

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt mehrere Möglichkeiten.

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

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

Autor: Rolf Magnus (Gast)
Datum:

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

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

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

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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Sven P. schrieb:
>> Gibt mehrere Möglichkeiten.
>>
>> Wenn der Vektor immer gleichlang ist:
>
> void funktion(int vektor[10]);
> 
>
> 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in C++ könnte man die Array-Länge als Template-Parameter vom Compiler 
automatisch einfüllen lassen, mit Konstrukten wie:
  namespace {
    template<typename text>
    class something_i {};

    template<int len>
    class something_i<char[len]> {
    public:
      static void do_something(const char op[len]) {
         for(int i=0; i<len; ++i) {...}
      }
    };
  }
  template<typename text>
  void do_something(const text & op) {
    something_i<text>::do_something(op);
  }

  ....

  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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.