2009-07-21 5 views
1

NextUnit()という名前の関数から得たデータ "somebytes"を "output.txt"という名前のファイルに書きたいと思いますが、私が書いたコードは動作しません。ファイルを開くと、私の "somebytes"のようには見えません。関数からメモリのブロックを取得し、それをファイルに書き込むにはどうすればよいですか?

#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

フォーマットを修正するには、各コード行の前に4つのスペースを入れます。 –

+1

あなたのコードをすべてハイライトしてから、0と1のボタンを押すと、自動的にインデントされます。 –

+0

なぜこのタグはC++ですか?私にはCのように見えます。 – jalf

答えて

3

関数(別名解放されたスタックアドレス)からローカルアドレスを戻しています。次の関数を呼び出すと変更されます。

イーサはちょうど

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

またはあなたが、その後も自由後で...

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

あなたはUnit[256]を宣言したする必要があります新しいメモリ構造、にそれをコピーするグローバル定数を返しますサブプロシージャ内のスタックに格納されます。しかし、NextUnit()が返ってくると、スコープされた変数は範囲外になり、もはや有効なメモリを指していません。

newでメモリを割り当てた後、呼び出し元でメモリを解放するか、呼び出し元が事前割り当てメモリへのポインタを渡すことを検討してください。

1

あなたは というローカルアドレスを返しています。エーテルはちょうど返す

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

ので、それが一定だ、またはあなたは、私が引用した上でコメントするのに十分なモジョを持っていない、後で...

にも自由に必要 ます 新しいメモリstucture、にそれをコピーします私はこれを新しい答えとしなければなりません。

彼の答えは正しいことを言っているが、間違っていた。

あなたのコードは、NextUnit()関数内のローカル変数のアドレスを返しています。それをしないでください。これは悪いです。彼が提案したことをしてください。あなたは関数の実装外の変数をどのように処理するかを決めることができ

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

この方法:私はこのようにそれを書き換えるでしょう

+0

ああ私の神よ、私もあまりにもありがとう... –

1

あなたがC++を使用している場合

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

しかし、文字列のコピーは常に先頭に始まります、あなたはstrcatの混乱ですか? –

+0

はい、私は完全にstrcatだと思っていました:) –

1

、次のようにするとより良い方法です:

#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; 
} 

そして、あなたがそれに慣れたら、次に学ぶべきことはRAIIです。

+0

真実ですが、コードが期待したとおりに行動しないという彼の質問には答えません。 – jalf

+0

これは有効な点ですが、彼がC++でコーディングしている場合、彼が投稿したコードは適切なトラックにさえありません。何が問題なのかを詳細に説明することができますが、最終的にC++でファイルにデータを正しく書き込む方法を学ぶことはもうありません。 –

0

NextUnitは、その関数のローカルな配列であるUnitのアドレスを返します。つまり、スタックに割り当てられ、関数が返ってきたら "解放"され、戻り値は無効になります。動的に新しい文字列にNextUnitが呼び出されるたびに割り当てる

  • :することができます。この問題を解決するために

    。その場合、メモリはを削除する必要があります。

  • グローバル文字列を作成します。これは小さな "テスト"アプリケーションでは問題ありませんが、一般的にはグローバル変数の使用はお勧めしません。
  • mainは文字列を(動的にまたはスタック上に)割り当て、NextUnitのパラメータとして渡し、その文字列にNextUnitをコピーさせます。
0

ここにはいくつか問題があります。主なものは、NextUnit()がスタックにバッファを割り当てているため、アドレスを返そうとすると有効範囲外になるということです。

これをCスタイルの解決策で修正するには、バッファ用のスペースをmallocし、mallocが返すポインタを返すことができます。

私は最初のステップは、より多くの次のようにコードを書き換えることかもしれないと思う。実際、それはだと「スタック」変数の意味であるNextUnit内のローカル変数として宣言

#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、C++でC関数を使用しているからといって、mallac/freeを抜かなければならないわけではありません.C++はコンストラクタとの一貫性のために新しく削除するだけです。 –

+0

申し訳ありません - コードのどの部分がC++ですか?彼のCヘッダーファイル?彼のC文字列関数? OO設計の彼の欠如?私はこのCの質問のために彼をC++に切り替える理由を見ません。 – mrduclaw

0

「ユニット」 lifetimeはNextUnitが返されない限りです。

したがって、NextUnitはまだ返されていませんが、「somebytes」をコピーするとOKです。これは印刷されます。 NextUnitが返ると、Unitはスタックから解放され、mainのポインタsomedataは有効なものを指していません。

ここはクイックフィックスです。私はまだこの方法でプログラムを書くのはお勧めしませんが、それは最小限の変更です。

#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); 
} 

これはうまくいきますが、実際にはグローバルの場合、Unitのアドレスを返すのは無意味です!

0

staticとしてUnitを宣言します。

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

しかし、あなたがC++コンパイラを使用する場合は、std::string代わりのchar*を使用することを検討すべきです。 std::stringはより安全で、すべての割り当て/割り当て解除ジョブを実行します。

関連する問題