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);
>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.
@ 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
...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?
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!
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.
@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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.