char *recvmsg(){
char buffer[1024];
return buffer;
}
int main(){
char *reply = recvmsg();
.....
}
Ich bekomme eine Warnung:
Warnung C4172: Rückgabeadresse der lokalen Variablen oder temporär
char *recvmsg(){
char buffer[1024];
return buffer;
}
int main(){
char *reply = recvmsg();
.....
}
Ich bekomme eine Warnung:
Warnung C4172: Rückgabeadresse der lokalen Variablen oder temporär
Nawaz
ich würde vorschlagen std::vector<char>
:
std::vector<char> recvmsg()
{
std::vector<char> buffer(1024);
//..
return buffer;
}
int main()
{
std::vector<char> reply = recvmsg();
}
Und dann, wenn Sie jemals brauchen char*
in Ihrem Code, dann können Sie verwenden &reply[0]
Wann immer du willst. Zum Beispiel,
void f(const char* data, size_t size) {}
f(&reply[0], reply.size());
Und du bist fertig. Das heißt, wenn Sie die C-API verwenden, können Sie sie weiterhin verwenden std::vector
wie Sie passieren können &reply[0]
an die C-API (wie oben gezeigt) und reply
zur C++-API.
Die Quintessenz ist: Vermeiden Sie die Verwendung new
so viel wie möglich. Wenn du benutzt new
dann müssen Sie es selbst verwalten, und Sie müssen delete
wenn du es nicht brauchst.
hehe, das OP Tat Stimmen Sie für C++, also sollte es so sein
– sehen
14. Oktober 2011 um 15:43 Uhr
Das OP könnte auch gebrauchen std::string
.
– Thomas Matthäus
14. Oktober 2011 um 16:13 Uhr
@ThomasMatthews: Wenn Sie die Daten (vom Typ char*
) als Puffer im Gegensatz zu Schnurdann glaube ich std::vector<char>
vermittelt das besser ohne Mehrdeutigkeit, als std::string
.
– Nawaz
27. August 2018 um 13:26 Uhr
.. Oder man könnte es gebrauchen using buffer_t = std::vector<char>;
(oder vielleicht, using buffer_t = std::string;
), dann benutze buffer_t
; vielleicht ist das passender. (Wünschte, C++ hätte stark Pseudonym!)
– Nawaz
27. August 2018 um 13:30 Uhr
Luchian Grigore
Sie müssen Ihr Char-Array dynamisch zuweisen:
char *recvmsg(){
char* buffer = new char[1024];
return buffer;
}
für C++ und
char *recvmsg(){
char* buffer = malloc(1024);
return buffer;
}
für C.
Was passiert, ist, dass sich Ihre Variable ohne dynamische Zuweisung auf dem Stapel der Funktion befindet und daher beim Beenden zerstört wird. Deshalb bekommst du die Warnung. Die Zuweisung auf dem Heap verhindert dies, aber Sie müssen vorsichtig sein und den Speicher freigeben, sobald Sie damit fertig sind delete[]
.
Verwenden new
in C++ macht es nicht zu einer Lösung im C++-Stil. Die Lösung im C++-Stil ist std::vector<char>
statt Rohzeiger char*
.
– Nawaz
14. Oktober 2011 um 15:53 Uhr
Sie können std::vector nicht wirklich mit p/invoke verwenden, soweit ich weiß, wenn Sie irgendwelche Interop-Anforderungen mit c# oder VB haben
– Tom Fobear
14. Oktober 2011 um 17:11 Uhr
ist nicht malloc( 1024 * sizeof( char ) )
besser?
– süß
10. August 2013 um 23:21 Uhr
@sazary Geschmackssache, sizeof char ist immer 1.
– Luchian Grigore
11. August 2013 um 12:47 Uhr
Es ist nicht notwendig, dass malloc verwendet wird, siehe die Antwort von karl oder mir.
– Jürgen
17. Februar 2015 um 0:41 Uhr
Mystisch
Die Warnmeldung ist korrekt. Sie geben die Adresse eines lokalen Arrays zurück, das nach der Rückkehr der Funktion verschwindet.
Sie können dies mit dynamischer Speicherzuweisung tun:
char *recvmsg(){
char *buffer = (char*)malloc(1024);
return buffer;
}
Der Haken ist, dass Sie sich vergewissern müssen free()
den Zeiger später, um ein Speicherleck zu vermeiden.
Alternativ können Sie den Puffer an die Funktion übergeben.
void recvmsg(char *buffer,int buffer_size){
// write to buffer
}
void main(){
char buffer[1024];
recvmsg(buffer,1024);
}
Dies vermeidet die Notwendigkeit einer Speicherzuordnung. Dies ist eigentlich der bevorzugte Weg, dies zu tun.
Ich würde sicherlich nicht schlage dies vor. In C++, std::vector<char>
ist bessere Lösung. Diese Antwort schlägt eine Lösung im C-Stil vor, aber die Frage ist mit C++ gekennzeichnet.
– Nawaz
14. Oktober 2011 um 15:46 Uhr
Warum hatte ich den Eindruck, dass es mit C gekennzeichnet war … Aber ja, Sie haben Recht, Vektor wird bevorzugt.
– Mystisch
14. Oktober 2011 um 15:49 Uhr
Das Problem ist, dass buffer
lebt auf dem Stack und verschwindet in dem Moment, in dem Sie es verlassen recvmsg
.
Du könntest zuordnen buffer
auf dem haufen:
char *recvmsg(){
char *buffer = malloc(1024);
return buffer;
}
Beachten Sie, dass jetzt der Aufrufer für die Entsorgung des zugewiesenen Speichers verantwortlich ist:
void main(){
char *reply = recvmsg();
free(reply);
}
Sie haben ein paar Optionen … Die Art und Weise, wie Sie es jetzt tun, wird zu undefiniertem Verhalten führen, da das Array den Gültigkeitsbereich verlässt, sobald die Funktion zurückkehrt. Eine Möglichkeit besteht also darin, den Speicher dynamisch zuzuweisen.
char * recmsg()
{
char * array = new char[128];
return array;
}
Denken Sie nur daran, es auf diese Weise mit delete zu bereinigen (oder kostenlos, wenn Sie malloc verwendet haben). Zweitens könnten Sie einen Parameter verwenden …
void recmsg(char * message, int size)
{
if (message == 0)
message = new char[size];
}
Auch hier gilt wieder das Gleiche wie beim Vorhergehenden. Beachten Sie auch die Überprüfung auf 0, um sicherzustellen, dass Sie nicht new auf einen bereits zugewiesenen Zeiger aufrufen.
Zuletzt könnten Sie einen Vektor verwenden.
std::vector<char> recmsg()
{
std::vector<char> temp;
//do stuff with vector here
return temp;
}
Shubhankar Sisodia
char *recvmsg(){
char *buffer = new char;
cout<<"\nENTER NAME : ";
cin>> buffer;
return buffer;
}
int main(){
char *reply = recvmsg();
cout<<reply;
}
Jürgen
Nur um das Bild zu vervollständigen:
Es ist nicht notwendig, Speicher mit malloc zu allokieren. Sie können den Puffer auch auf dem Stapel erstellen, aber Sie müssen ihn auf einem Stapelrahmen erstellen, der so lange lebt, wie der Konsument des Puffers lebt. Das war der Fehler des OP – als der Angerufene fertig war, wurde der Puffer gelöscht und der Aufrufer erhielt einen ungültigen Zeiger.
Was Sie also tun können, ist Folgendes:
void recvmsg(char *buffer, size_t size) {
... do what you want ...
}
void main(void) {
char buffer[1024];
recvmsg(buffer, sizeof(buffer));
}
Sie sollten sich entweder mit C oder C++ zufrieden geben, da eine gute Antwort davon abhängt.
– PlasmaHH
14. Oktober 2011 um 15:38 Uhr
Wollten Sie auch Antworten für C++ oder nur für C?
– JoG
14. Oktober 2011 um 15:39 Uhr
Ach und btw.
void main
ist falsch.– PlasmaHH
14. Oktober 2011 um 15:41 Uhr
Wenn das Ding, von dem Sie C++ lernen, verwendet wird
void main
es ist höchstwahrscheinlich Mist. Ich empfehle eine gut Einführendes C++-Buch.– R.Martinho Fernandes
14. Oktober 2011 um 15:50 Uhr
Es kann in Ordnung sein, die Warnung zu ignorieren, wenn Sie die Rückgabe von verwenden
*recvmsg
nur als Eingabe für eine Funktion wiestrcpy
in der aufrufenden Routine, da die Funktion return nicht in einer Zuweisung verwendet wird.– Laurie Stearn
29. März 2020 um 4:09 Uhr