ここから本文です

C++でメモリーの動的確保でエラーが出る 今

yume0222jpさん

2014/11/2208:50:30

C++でメモリーの動的確保でエラーが出る

ideone.com/OrvkFvのような画面をキャプチャーするプログラムを作っているのですが、wchar_t* const tFilename = new wchar_t[(cchBufW + FILE_NAME_SUB_LEN + 1) * sizeof *tFilename];
で確保したものを
delete[] tFilename;
とすると
HEAP[Scatto_continuo_v2.exe]: Heap block at 006E2020 modified at 006E20BC past requested size of 94
Scatto_continuo_v2.exe によってブレークポイントが発生しました。

プログラム '[8556] Scatto_continuo_v2.exe' はコード 0 (0x0) で終了しました。
となりコケます。なんとなく動的確保について根本的に間違っている気はしますが、原因が突き止められません。
関係しそうなところだけ抜き出したコードが
ideone.com/tvFVBQ
です。
またその時のVisual Studio2013Explessのデバッグ画面です。
imgur.com/VqrV8u1
よろしくお願いします

閲覧数:
286
回答数:
4
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

n2q37さん

2014/11/2210:01:32

まず、

wchar_t* const tFilename = new wchar_t[(cchBufW + FILE_NAME_SUB_LEN + 1) * sizeof *tFilename];

これ。掛け算が不要です。 「* sizeof *tFilename」この部分です。でも余分に割り付けているだけですから、動作に支障は出ませんよ。

次に、こうやって割り付けたメモリの扱いですが、Determine_Filename 関数で、

_stprintf_s(tfilename, _tcslen(tfilename) + 1, __T("%s"), tcore_filename);

こうやってますね。「_tcslen(tfilename) + 1」が正しくない。これなら異常がでても不思議はありません。このメモリ領域の内容はまったく未初期化ですから。これから文字列で満たそうという場面ですので、_tcslen を使用するというのは考えられません。単純ミスかどうか。もし、意味が分かっていないとしたら恐いです。ミスならいいです。誰にでもそういうことはありますので。

こんな具合でちょっと見ただけで怪しいコーディングが出てきます。他にもあるかもしれませんよ。都合により全体は見ませんけど。

《備考》

配列ということで new してるわけで、delete [] の形にするのは当たり前。当然過ぎる。それを delete tFilename; にするっていう形はありえないわ。まあ、wchar_t 型ですからそれでも問題ないんだけど。混乱なさらないようにね。

  • n2q37さん

    2014/11/2210:13:14

    あと、TCHAR 型の扱いに混乱があるように見えてます。もし慣れていないとすると、その状況で応用プログラムは早すぎるかも。必要以上に複雑度が増している状況のように思えるんですよね。これだと解決に必要な技術力がその分増えてしまうかもしれませんよ。でも見立て違いかもしれません。そうだとしたら申し訳ない。勘違いかもしれないのでね。失礼をお詫びします。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2014/11/29 10:29:47

皆様本当に回答ありがとうございました。
自分でも無茶な質問だとは重々承知していたのですが、こんなにもたくさん回答をいただきありがとうございます。
一応解決し(全く別のところでまたバグって動かない&時間不足で検証不十分)たので、BAを決めさせていただきます。
Twitter経由で回答していただいた方もありがとうございます。

ベストアンサー以外の回答

1〜3件/3件中

並び替え:回答日時の
新しい順
|古い順

mavericktseさん

2014/11/2212:03:21

Buffer overflow です:

_stprintf_s(tfilename, _tcslen(tfilename) + 1, __T("%s"), tcore_filename);
のところ
_tcslen(tfilename) → _tcslen(tfilename)/2

他の_tcslen()も /2 にして、解決できるはず

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

foobar7979さん

2014/11/2211:43:54

以下が、鉄則です。
・new で確保したものは delete で開放する。
・new[] で確保したものは delete[] で開放する。

operator new, operator delete

operator new[], operator delete[]
は、別物です。

だから、質問文に書かれてる内容だけ読めば、あなたのやってることは、正しい、

けど、「落ちる」のは、あなたの書いたコードにバグがあるから。
メモリ破壊するようなコードがあるんです、たぶん。
・new[] で確保した配列メモリを、範囲を超えて上書きしちゃうコードがある
といった。

それをこんなとこで「他人にデバッグ頼む」のは、無理があるよ。

k032yfさん

2014/11/2209:13:59

yume0222jpさん

delete tFilename;
かな?

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問や知恵ノートは選択されたID/ニックネームのMy知恵袋で確認できます。