Wie gibt man ein lokales Array in C++ zurück?

Lesezeit: 5 Minuten
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

  • 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 wie strcpy in der aufrufenden Routine, da die Funktion return nicht in einer Zuweisung verwendet wird.

    – Laurie Stearn

    29. März 2020 um 4:09 Uhr


Wie gibt man ein lokales Array in C zuruck
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::vectorwie 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 newdann 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


Wie gibt man ein lokales Array in C zuruck
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

1646641210 58 Wie gibt man ein lokales Array in C zuruck
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;
}

Wie gibt man ein lokales Array in C zuruck
Shubhankar Sisodia

char *recvmsg(){
    char *buffer = new char;
    cout<<"\nENTER NAME : ";
    cin>> buffer;
    return buffer;
}

int main(){
    char *reply = recvmsg();
    cout<<reply;
}

1646641211 788 Wie gibt man ein lokales Array in C zuruck
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));
}

964330cookie-checkWie gibt man ein lokales Array in C++ zurück?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy