2009-07-21 3 views
1

Ich möchte die Daten "somebytes" schreiben, die ich von einer Funktion namens NextUnit() in eine Datei namens "output.txt" bekomme, aber der Code, den ich schrieb, funktioniert nicht. Wenn ich die Datei öffne, sieht es nicht wie meine "Somebytes" aus. Hier ist der Code:Wie kann ich einen Speicherblock von einer Funktion erhalten und in eine Datei schreiben?

#include <stdio.h> 
#include <string.h> 

char* NextUnit() 
{ 
    char Unit[256]; 
    strcpy(Unit,"somebytes"); 
    return &Unit[0]; 
} 

int main() 
{ 
    FILE *ourfile; 
    ourfile=fopen("output.txt","wb"); 
    char* somedata; 
    somedata=NextUnit(); 
    printf("%s\n",somedata); 
    fwrite(somedata,1,strlen(somedata),ourfile); 
    fclose(ourfile); 
} 
+2

Um die Formatierung zu korrigieren, setzen Sie 4 Leerzeichen vor jeder Codezeile. –

+1

Oder markieren Sie alle Ihren Code und drücken Sie dann die Taste mit 0 und 1 - das wird automatisch für Sie einrücken. –

+0

Warum ist dieses C++ markiert? Sieht für mich wie C aus. – jalf

Antwort

3

Sie die lokale Adresse aus einer Funktion zurückkehrt (aka freigegeben Stapeladresse). Dies wird dann geändert, sobald Sie die nächste Funktion aufrufen.

Äther zurückkehren nur eine globale Konstante

const char* NextUnit() { return "somebytes"; } 

oder es in eine neue Speicherstruktur zu kopieren, die Sie dann später auch kostenlos müssen ...

char* NextUnit() 
{ 
    char* newstr = new char[256]; 
    strcpy(newstr,"somebytes"); 
    return newstr; 
} 

// some code later 
char* tmpstr = NextUnit(); 

// do writing stuff 

// free memory 
delete tmpstr; 
1

Sie Unit[256] deklariert haben auf dem Stapel in einer Unterprozedur. Aber wenn Ihre NextUnit() zurückgibt, geht die Variable, die darauf beschränkt war, außerhalb des Geltungsbereichs, und Sie zeigen nicht mehr auf gültigen Speicher.

Ziehen Sie in Betracht, den Speicher mit new zuzuweisen und dann im Aufrufer freizugeben oder den Anrufer einen Zeiger auf den zuvor zugewiesenen Speicher übergeben zu lassen.

1

Sie geben die lokale Adresse eine Funktion zurück. Ether einfach zurück

const char * NextUnit() {zurück "somebytes"; }

so ist es konstant ist, oder in einen neue Speicher stucture zu kopieren, die Sie dann auch später kostenlos müssen ...

ich auf dem zitierten Kommentar nicht genug mojo haben antworte, also muss ich das als eine neue Antwort aussprechen.

Seine Antwort versucht, das Richtige zu sagen, aber es kam falsch.

Ihr Code gibt die Adresse einer lokalen Variablen innerhalb der NextUnit() - Funktion zurück. Tu das nicht. Es ist schlecht. Tu, was er vorgeschlagen hat.

+0

oh mein Gott, ich bin auch, danke ... –

1

Ich würde es so umschreiben:

char *NextUnit(char *src) 
{ 
    strcpy(src, "somebytes"); 
    return src; 
} 

Auf diese Weise können Sie entscheiden, was mit dem variablen außerhalb die Funktion Implementierung zu tun:

char Unit[256]; 
char *somedata = NextUnit(Unit); 
+1

aber Zeichenfolge kopieren immer am Anfang beginnen, sind Sie von strcat verwirren? –

+0

Ja, ich dachte total, es war strcat :) –

1

Wenn Sie C++ verwenden, die Folgendes ist ein viel besserer Weg, dies zu umgehen:

#include <iostream> 
#include <string> 

using namespace std; 

int main(int argc, char ** argv) 
{ 
    ofstream outFile; 

    outFile.open("output.txt"); 
    outFile << "someBytes"; 
    outFile.close(); 

    return 0; 
} 

Und sobald Sie damit vertraut sind, ist das nächste, was Sie über RAII erfahren.

+0

wahr, aber es beantwortet nicht seine Frage, wh der Code nicht das tut, was er erwartet. – jalf

+0

Das ist ein gültiger Punkt, aber wenn er in C++ programmiert, ist der von ihm gepostete Code nicht einmal auf dem richtigen Weg. Wir können im Detail erklären, was damit nicht stimmt, aber am Ende wird er nicht weiter voraus sein und lernen, wie man Daten in Dateien in C++ schreibt. –

0

NextUnit gibt die Adresse von Unit zurück, die ein Array lokal für diese Funktion ist. Das bedeutet, dass es auf dem Stapel zugeordnet und "freigegeben" wird, wenn die Funktion zurückkehrt, wodurch der Rückgabewert ungültig wird.

Um dieses Problem zu lösen, können Sie:

  • dynamisch eine neue Zeichenfolge jedes Mal zuweisen NextUnit aufgerufen wird. Beachten Sie, dass Sie in diesem Fall den Speicher später löschen müssen.
  • Erstellen Sie eine globale Zeichenfolge. Das ist gut für eine kleine "Test" -Anwendung, aber im Allgemeinen wird die Verwendung von globalen Variablen abgeraten.
  • Lassen Sie eine Zeichenfolge (entweder dynamisch oder auf dem Stapel) zu, übergeben Sie sie als Parameter an NextUnit, und kopieren Sie NextUnit in diese Zeichenfolge.
0

Sie haben hier ein paar Probleme. Die wichtigste, glaube ich, ist, dass NextUnit() den Puffer auf dem Stack zuweist und Sie effektiv den Gültigkeitsbereich verlassen, wenn Sie versuchen, die Adresse zurückzugeben.

Sie können dies in einer C-style-Lösung beheben, indem Sie Speicherplatz für den Puffer mallocing und den Zeiger zurückgeben, der malloc zurückgibt.

Ich denke, ein erster Schritt könnte den Code, um etwas mehr wie folgt neu zu schreiben sein:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

char* NextUnit() 
{ 
    char *Unit = (char *)malloc(256); 
    memset(Unit, 0, sizeof(Unit)); 
    strcpy(Unit,"somebytes"); 
    return Unit; 
} 

int main() 
{ 
    FILE *ourfile; 
    ourfile=fopen("output.txt","wb"); 
    char* somedata; 
    somedata=NextUnit(); 
    printf("%s\n",somedata); 
    //fwrite(somedata,1,strlen(somedata),ourfile); 
    fprintf(ourfile, somedata); 
    free(somedata); 
    fclose(ourfile); 
} 
+0

eek, nur weil er C-Funktionen in C++ benutzt, bedeutet das nicht, dass wir mallac/free herausziehen müssen, es ist C++, bleiben Sie einfach bei new und löschen Sie aus Gründen der Konsistenz mit Konstruktoren. –

+0

Entschuldigung - welcher Teil seines Codes war C++? Seine C-Header-Dateien? Seine C-Saite funktioniert? Sein Mangel an OO-Design? Ich sehe keinen Grund, ihn für diese C-Frage zu C++ zu wechseln. – mrduclaw

0

„Einheit“ als lokale Variable innerhalb NextUnit erklärt, die tatsächlich ein „Stapel“ Variable Bedeutung ist, dass es Lebensdauer ist nur so lange wie NextUnit nicht zurückgegeben wurde.

So, während NextUnit noch nicht zurückgekehrt ist, ist das Kopieren von "somebytes" in es OK, als wird es ausgedruckt. Sobald NextUnit zurückkehrt, wird Unit vom Stack freigegeben und der Zeiger somedata in main wird nicht auf etwas Gültiges zeigen.

Hier ist eine schnelle Lösung. Ich empfehle es immer noch nicht, auf diese Weise Programme zu schreiben, aber es sind die wenigsten Änderungen.

#include <stdio.h> 
#include <string.h> 

char Unit[256]; 

char* NextUnit() 
{ 

    strcpy(Unit,"somebytes"); 
    return &Unit[0]; 
} 

int main() 
{ 
    FILE *ourfile; 
    ourfile=fopen("output.txt","wb"); 
    char* somedata; 
    somedata=NextUnit(); 
    printf("%s\n",somedata); 
    fwrite(somedata,1,strlen(somedata),ourfile); 
    fclose(ourfile); 
} 

Das funktioniert, aber es ist sinnlos, die Adresse der Einheit zurückzugeben, wenn es tatsächlich global ist!

0

Deklarieren Unit als static:

char* NextUnit() 
{ 
    static char Unit[256]; 
    strcpy(Unit,"somebytes"); 
    return &Unit[0]; 
}

Aber wenn Sie C++ Compiler verwenden, sollten Sie std::string statt char* betrachten verwenden. std::string ist sicherer und erledigt alle Zuweisungs/Freigabe-Jobs für Sie.

Verwandte Themen