Arduino-C++: Typ-Problem, erbitte Hilfe

OP (Firma: Q3) #7135520
In den Beispielprogrammen der Netzwerk-Library für nRF24L01-Transmitter 
(https://schullebernd.de/master-slave-netzwerk-mit-nrf24l01-und-arduino-esp8266/) 
taucht folgendes Code-Segment auf, was auch funktioniert:
1
  ...
2
  char* message = "test message.";
3
  Serial.println(message); //<--- das zeigt auch 'test message." an!
4
  nd.sendToDevice(nd.NetworkDevice.MasterMAC, message, strlen(message) + 1);
5
  ...

Nun benötige ich aber für message einen variablen String und habe mich 
mit der Typumwandung herumgequält. Der folgende Code wird zwar ohne 
Fehler compiliert, aber Serial.println(message) ist leer und auch das 
was gesendet wird. Der Empfänger stellt zwar fest, es wurde etwas 
gesendet, aber auch dort ist die Ausgabe in den seriellen Monitor leer 
...
1
  ...
2
  String mystr = "test message.";
3
  char* message;
4
  mystr.toCharArray(message, mystr.length());
5
  Serial.println(message); //<--- das gibt eine leere Zeile
6
  nd.sendToDevice(nd.NetworkDevice.MasterMAC, message, strlen(message) + 1);
7
  ...

Die Anzahl der gesendeten Zeichen wird vom Empfänger richtig erkannt, 
nur die Sendung selbst ist quasi unsichtbar und belegt im seriellen 
Monitor die Länge null. Code auf Empfängerseite:
1
  ...
2
  int messageSize = networkDevice.available();
3
  if (messageSize > 0)
4
  {
5
    Serial.print("receive: ");
6
    Serial.print((char*)networkDevice.getMessage());
7
    Serial.print(" - ");
8
    Serial.println(messageSize);
9
  }
10
  ...

Kann mir bitte mal jemand zeigen, wie es richtig geht? Ist bestimmt nur 
eine Kleinigkeit. Danke.
Gast #7135532
Seit wann gibt es toCharArry in C++?
Du knnst einfach mystr.c_str() machen um enen zeiger darauf zu 
bekommn...

Wenn du den String erst kopieren möchtest:

char* message = new char[mystr.length()+1]
memcpy(message, mystr.c_str(), mystr.length()+1)
Gast #7135536
Der Buffer muss auch eine Größe haben.
So werden die nachfolgenden Daten im Speicher überschrieben.
1
char message[länge];

oder dynamisch allociert und dann dem Zeiger zugewiesen.
#7135573
Frank E. schrieb:
> Wilhelm M. schrieb:
>> Frank E. schrieb:
>>> Danke! Die zwei Zeilen von o.O. mit memcpy tun, was sie sollen.
>>
>> Und schon haben wir ein Speicherleck ...
>
> Ja, habe ich inzwischen auch gemerkt, läuft nur immer eine zeitlang ...

Warum willst Du es überhaupt in ein C-Array kopieren?
Weil Du eigentlich snprintf() verwenden willst?

Du kannst das C-Array lokal auf dem Stack allokieren, wenn Dein Stack 
nicht überläuft.
Du kannst es statisch allokieren.
Du kannst es (wie oben) dynamsich allokieren, dann aber wieder löschen.
Du kannst auch std::array oder std::vector nehmen.
Du kannst auch std::unique_ptr<[]> nehmen.
#7135575
Frank E. schrieb:
>
1
>  ...
2
>     mybuf = "Test " + String(cnt1);
3
>     char message[mybuf.length()+1];
4
>     memcpy(message, mybuf.c_str(),mybuf.length()+1);
5
>  ...
6
>
>
> das tut aber jetzt!

Klaro.
Ich hoffe, Du verstehst den Unterschied. Falls nicht, kauf die ein 
C-Buck, besser eines über C++ !

P.S.: Willst Du tatsächlich das Sentinel mit senden?
Gast #7135585
Und was spricht dagegen, den einfachsten Ansatz zu wählen?
1
String mystr = "test message.";
2

3
nd.sendToDevice(nd.NetworkDevice.MasterMAC, mystr.c_str(), mystr.length() + 1);
Gast #7135639
Frank E. schrieb:
> Wilhelm M. schrieb:
>> Frank E. schrieb:
>>> Danke! Die zwei Zeilen von o.O. mit memcpy tun, was sie sollen.
>>
>> Und schon haben wir ein Speicherleck ...
>
> Ja, habe ich inzwischen auch gemerkt, läuft nur immer eine zeitlang ...

musst natürlich mit free den Speicher wieder freigeben...
free(message)

Aber ja unnötig ist das ganze.
#7135646
o.O schrieb:
> Frank E. schrieb:
>> Wilhelm M. schrieb:
>>> Frank E. schrieb:
>>>> Danke! Die zwei Zeilen von o.O. mit memcpy tun, was sie sollen.
>>>
>>> Und schon haben wir ein Speicherleck ...
>>
>> Ja, habe ich inzwischen auch gemerkt, läuft nur immer eine zeitlang ...
>
> musst natürlich mit free den Speicher wieder freigeben...
> free(message)

malloc/calloc/realloc -> free
new -> delete

Aber das ist alles old-school (und so auch nicht exception-safe).
Nimm std::unique_ptr.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 4 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.