www.mikrocontroller.net

Forum: Compiler & IDEs sizeof Frage


Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum liefert sizeof(sendstring) den Wert 2?

sowohl bei:
void can_send_mg (char sendstring[8], long msid, int m_box)
{
AnzZeichen=sizeof(sendstring);
...

als auch bei:
void can_send_mg (char *sendstring, long msid, int m_box)
{
AnzZeichen=sizeof(sendstring);
...


can_send_mg ("TestMB01", 8192 + Controller_ID,14);

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>void can_send_mg (char sendstring[8], long msid, int m_box)

AFAIK ist es nicht möglich, so Speicher für ein Array zu reservieren!
Überlege mal, wie ein Prototyp einer solchen Funktion aussehen würde
und was Du (genau genommen) dieser Funktion in jedem Fall übergeben
müsstest. Das 'char sendstring[8]' wird hier wohl auf 'char
sendstring[]' reduziert, was 'char *sendstring', und damit einem
Pointer, entspricht. Ein Pointer des Typs 'char *' benötigt zwei
Bytes Platz im RAM.
Es ist übrigens Grundsätzlich schlecht array 'by Value' übergeben zu
wollen. Besser ist es, die Daten des Arrays 'by reference' zu
übergeben und nötigenfalls zu kopieren, wobei das Kopieren relativ
Zeitinsiv sein dürfte.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ flyingwolf

Das problem ist einfach, dass Du mit sizeof(sendstring) immer die Größe
der Variable "sendstring" im Speicher bestimmst. Diese Variable ist
aber ein Zeiger auf den Anfang Deines definierten Arrays. Zeiger
wiederum sind bei dem von Dir verwendeten Compiler anscheinend 16 bit
(2 byte) lang.

Wenn Du wirklich die Länge eines Strings bestimmen willst, dann geht
afaik nur bei 0-terminierten Strings, sprich welche, bei denen das
letzte Zeichen 0x00 ist. Macht man dann so :

uint8_t ui8StringLength;
for (ui8StringLength=0; sendstring[ui8StringLength];
ui8StringLength++);

Nach diesen Zeilen steht in der Variable ui8StringLength die Länge
Deines Strings.

@oldbug
So Konstruktionen sind glaube ich schon möglich, aber frag' mich bloß
nicht, ob das nur bei manchen Compilern geht oder ob es Standard in C
ist. Nix genaues weiß ich nicht.

MfG, Daniel

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Es ist übrigens Grundsätzlich schlecht array 'by Value'????
übergeben zu wollen.

Bezieht sich das auf char sendstring[8]? Das war nur ein Versuch weil
ich mir erhofft habe damit die richtige Länge des Strings zu
rückgeliefert zu bekommen.

... Besser ist es, die Daten des Arrays 'by reference' zu
übergeben und nötigenfalls zu kopieren, wobei das Kopieren relativ
Zeitinsiv sein dürfte.

Das bedarf einer näheren Erklärung.

Welchen Weg gibt es, zu erfahren, wieviele Zeichen *sendstring enthält?

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nene :-)

Ich hab das schon so halbwegs überprüft. Allerdings hab ich mir nicht
die Speicherauslastung beim Betreten der Funktion angeschaut, weshalb
ich eigentlich nur vermuten kann, daß die 8 Bytes gar nicht erst
reserviert werden.

Hier ein Beispiel:

#include <stdio.h>

void foo(unsigned char *);
unsigned char baz[8], src[] = "TestMB01";

int
main(void)
{
        foo(src);

        return 0;
}

void
foo(unsigned char bar[8])
{
        unsigned char bay[8];
        printf("bar has %d bytes\n"
               "content consists of %d bytes\n"
               "baz and bay have %d and %d bytes and no content\n",
               sizeof(bar), strlen(bar), sizeof(baz), sizeof(bay));
        printf("btw: bar points to %p and src to %p\n",
               bar, src);
}

Kompilieren mit:

  $ gcc -O -ggdb -o foo.exe foo.c

Ausgabe:

bar has 4 bytes
content consists of 8 bytes
baz and bay have 8 and 8 bytes and no content
btw: bar points to 00402010 and src to 00402010

Wie man sehr schön erkennen kann zeigt 'bar' auf 'src' und nicht
auf neu reservierten Speicher!

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uebergabe von Arrays in C m.W. immer "by reference".
Laengenangabe ([8]) bei ersten Aufruf macht wenig Sinn (ohnehin
implizit Pointer). Wenn man wirklich einen String (="null
terminiert") senden will, ist die Laenge des Strings mit strlen
ermittelbar. Im Zweifel fuer CAN auf 8 Zeichen begrenzen. Ansonsten
Anzahl Zeichen (wird DLC) als Parameter zur Funktion mituebergeben.
Alternativ: ein "can_msg-Struct" als Parameter und DLC-Wert/DTA-Feld
vor dem Aufruf anlegen und (pointer auf) Struct-Objekt uebergeben.
Vorgehensweise ueber struct oft effektiver, da der Compiler auf Offsets
optimieren kann und nicht viele Regsiter fuer Parameter verwalten muss.

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Daniel
Sorry, Dein Post stand noch nicht bei mir drin, als ich die Antwort
geschrieben habe.

@all
erst mal Danke. ich werd es mal mit strlen probieren.

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.