2009-05-25 14 views
0

皆さん、私は理解できないヒープ破損エラーが発生しています。char *をC++に割り当てて解放する

char * c = (char *) malloc(1); 
// main loop 
_gcvt_s(c, 100, ball->get_X_Direction(), 10); 
     if(pushFont(c, (SCREEN_WIDTH - 30), (SCREEN_HEIGHT - 40), message, screen, 
font, textColor) == false) 
     { 
      //return 1; // error rendering text. 
     } 
// end main loop 
free(c); 

上記のコードは、単にその最初のパラメータとして* CHARを受け付け、画面上のテキストを置く私は_gcvt_sで、Cポインタを使用してpushFont()のみの時間です。それ以外は、私はcを使用しません。メインループの後でCをフリーズしようとすると、Visual Studioがヒープ(ヒープの破損)でエラーを取得したというエラーが表示されます。

pushFontの呼び出しをコメントアウトしても、エラーは発生します。

誰も私にヒープの破損を与えるキャラクター(ヒープに割り当てた1バイト)を解放する理由を誰にも説明できますか?

最後に、私のメインループはたくさんのものをやっていますが、バディと私はWinSocketでポンゲームを作っています。残りの本体はゲームのループです。私は投稿が必要だとは思っていませんでしたが、必要であればメインループ全体で投稿を更新しますが、私はmalloc()とfree()について理解していると思います。

おかげで、すべて、

+0

この質問を "C++"から "C"に戻すべきではないですか? –

答えて

9

は_gcvt_sは、割り当てられたバッファの最大サイズとして第二のパラメータを使用しませんか?あなたは1バイトを割り当てますが、_gcvt_sには100があることを伝えます。それで、バッファに最大100バイトまでヒープを破損させて書き込みます。その後、無料でクラッシュします。潜在的に100バイトにアクセスする場合は、100バイトを割り当てます。

EDIT:Cが文字列をどのように格納して操作するかを学ぶ必要があるようです。 Cは、ストリングの最後を示す余分な文字の後に連続したメモリーの連続で個々のバイトとしてストリングを保管します。この余分な文字はASCII値が0です(文字 '0'ではASCII 48ではありません)。だから、 "HELLO"のような文字列があれば、5バイトの文字とターミネータのそれぞれに1バイトずつ、6バイトのデータが必要です。

_gcvt_s()がバッファに値を返すためには、変換に必要なバイト数と余分な終了バイトを含める必要があります。 _gcvt_s()の場合、10文字の精度が求められます。しかし、小数点以下の余裕を確保する必要もあります。

は、この[ドキュメント](http://msdn.microsoft.com/en-us/library/a2a85fh5(VS.80).aspx)によると、バッファの最大必要なサイズのヘッダ内の#defineがあります:。_CVTBUFSIZEの例では、この問題であなたをそこに助けるべき

+0

私は1つのポストで2つの質問をしたくないが... 私の質問は、2番目のパラメータは、バッファのサイズをバイト数にしたい。私のコードでは、変換時に10の精度が必要でした。私の推論では、変換された文字を格納するために必要なバイト数が必要な場合、各文字が1バイトであれば、そこに10を入れる必要があります。エラー。何らかの理由で私は100を試して動作しますが、私は第2パラメータが何を求めているのか全く分かりません。 –

+2

これは非常に簡単です.2番目のパラメータは、_gcvt_s関数に、(mallocを使用して)割り当てられたバイト数を、最初のパラメータのバッファに伝えることです。あなたはmallocの最初のパラメータとして100を渡すべきです - これはあなたが割り当てたと言ったサイズと一致します –

+0

Ok、私はそれをすべて理解しています。どうもありがとうございました。私は純粋に私の理解のために1つのフォローアップを持っています(100バイトを渡すことは全く不要です)。なぜ、次のことはうまくいかないのですか? _gcvt_s(c、1、ball-> get_X_Direction()、1);私は1バイトを割り当てました。私はそれについて嘘をつきませんでした。そして、4番目のパラメータでは、1バイトの精度しか必要としませんでした。 –

3

なぜ必要なのです。ヒープを使用するために必要なのは、あなただけのローカル変数を使用することはできません1文字のスペースである場合:??私は_gcvt_s()を見つけることができるドキュメントによると

char c; 
_gcvt_s(&c... 

+0

ローカル変数を使用すると、メイン関数が巻き戻そうとしたときにスタック破損エラーが発生しました(私はエラーが発生したときに何が起こったのかと思いますが、プログラムを終了するまでは起こりません)。 –

+2

これは、_gcvt_sがポインタを使って2つ以上のcharを書き込むと起こります。その場合、より大きなバッファを渡す必要があります。 – PowerApp101

4

はバッファと長さを取りますそのbの最初の2つの議論である。

errno_t _gcvt_s( 
    char *buffer, 
    size_t sizeInBytes, 
    double value, 
    int digits 
); 

あなたmalloc()エド・バッファは、あなたはそれが100バイト長である_gcvt_s()を教え、1バイトの長さです。私はここで探し始めます。

1

フロートを格納するには複数のバイトが必要です。 1バイトよりも実用的な長さを割り当てる...

実際にはヒープは必要ありませんが、少し大きめの16バイトバッファを試して、_gcvt_sに正しいバッファ長を指定してください(あなたが与える魔法の100ではなく)。あなたがそれにいる間、あなたの定数を消してください。

const unsigned int cuFloatStringLength = 16; 
const unsigned int cuFloatStringPrecision = 10; 

char c[cuFloatStringLength]; 

_gcvt_s(c, cuFloatStringLength, ball->get_X_Direction(), cuFloatStringPrecision); 

問題が解決されるはずです。

+0

これはうまくいきました。また、cuFloatStringLengthを11に変更し、10文字と1つのNULLターミネータを使用できるようにしました。エラー。 12はエラーなしで動作しますが、11は失敗します。最後のバイト(12番目)が何を格納するのか知っていますか? –

+0

"cu"は "銅"のハンガリー表記ですか?あなたは本当に気にして、代わりに "ag"や "au"からあなたの定数を割り当ててください。 – bk1e

+0

私は以前のポスターの例に "cu"を使用しました。 –

関連する問題