変化を求める人

クリップボードの内容を取得しよう→_crtisvalidheappointerエラーで落ちる

   

前回の記事でClipboardを取得する際に発生したエラーについて

こちらのページの「クリップボードからデータを取得する」の部分をコピペしコンパイル、実行した際に発生した。
コンパイル時の環境によって起きるのかも。

実行時エラーの内容は _crtisvalidheappointer というもの。
軽くググったところ、このエラーはメモリアクセスがおかしいときに発生するらしい。
例えば、すでに開放してあるメモリ(?ポインタ?変数?)に対して free() を呼ぶとか。

エラーの原因は文字コード?

lstrcpyが怪しい

今回の場合、lstrcpy() をコメントアウトするとエラーが出なかった。
こいつがメモリを破壊しているのではないかと思われる。
だけど、サンプルコードは lstrcpyを使っているし、どこが問題なのか。

コンパイルの文字コード

クリップボードから取得した文字列を直接覗いたところ、文字化けしていた。
そのあたりを含めて、さらにググる。
すると文字化けに関連した情報で、
「VC++ のコンパイルオプションで文字コードが Unicode になっていないか?」
といった文言を見つけた。
もしかしたらこれかなあと、プロジェクトの文字セットを確認。確かにUnicodeになっていたのでマルチバイト文字に変更した。
そして、実行。エラーなし。文字化けなし。OK!

使う文字コードによってlstrcpyで動作がおかしくなる。ということであっているのだろうか?
それとも今回はたまたまエラーが消えただけなのだろうか?

こっちの方がベターか?

エラーは消えたけど。Unicodeに対応した方が後々いいのではなかろうか。と思いつつググったページをよく見ると、すぐ下あたりに書いてあった。

GetClipboardData(CF_TEXT);

GetClipboardData(CF_UNICODETEXT);

引数の指定を変更すればいいだけだった。
ただし、コンパイルの文字コードをマルチバイト文字にしているとエラーで落ちたりはしないが、動作がおかしい。

今回の結論

ということで、GetClipboardDataの引数は、
コンパイルの文字コードによって
「マルチバイト文字」にしている場合は「CF_TEXT」
「Unicode」にしている場合は「CF_UNICODETEXT」
とするのがよさそう。

 - C/C++ ,

スポンサーリンク

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

「>」、「<」を含む文字列をコピーしたら自動でエスケープ文字にするアプリを作った

以前、文字列置換の記事でちょこっと書いたものを実際に作ってみた。クリップボードの …

C言語(win32api)で文字列の置換。改善の余地あり

コピー → 置換 → ペースト。 ある文字列をコピーした際、既定した文字列で自動 …

Unicode?Ansi?Windowsでの文字列の表現が紛らわしい

エディットコントロールを作る際に「文字列リテラル」について考えたこと。 定義した …

エディットコントロールにクリップボードの内容を出力してみた

今回はテキスト入力を処理する「エディットコントロール」を作ってみた。 前回取得し …

クリップボードの内容を取得してみた

何を書けばいいのかわからなくなってきた。 行動指針が見つからない。今、自分は何を …