質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

8801閲覧

C#でCのDLLを使用するときにヒープ領域が破損してしまう。

rtKikuchi

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2016/01/26 08:14

C#からC言語で書かれたDLLを反復で何度も呼び出して使っています。
DLLは自作です。

しかし、DLLの内部で動的配列を多用しており、
メモリを解放するときにヒープ領域の破損が起きてしまいます。
しかも、破損が起きる呼び出しの回数も決まっておりません。
おおむね20回程度の呼び出しで、破損は必ず生じます。

元のコードを見てみましたが、領域を超えて、書き込みをしていることはないと思います。
また、Cで確認したときは、ヒープの破損は起きませんでした。

C#のコードは、Visual Studio 2015でデバッグしているため、
ヒープ領域がデフォルトで1MBらしく、それが不足しているのでは?思いましたが、
設定方法がいまいちわかりません。

C#なので、他のコンパイラもわかりません。

お手上げの状態です。
なにか、アドバイスをご教授願います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KoichiSugiyama

2016/01/26 10:29 編集

何点か確認したい点があります。 もとのC言語で作成したDLLはVisual Studioで作成したものでしょうか? C#側をリリースビルドして実行してもヒープ破壊が起きますか? Cの該当する関数のコード、呼び出し側のC#のコードを一部でも提示していただくことはできますか。 これらの点を開示していただいた方が有効なアドバイスが集まりやすいと思います。
yohhoy

2016/01/27 04:55

具体的なコードが無いことには何もわかりませんが、少なくともDLL側がエクスポートする関数の宣言、C#側のexterrn宣言、メモリ確保・解放周辺のコードを提示された方が良いです。
guest

回答2

0

皆さま、ご教授頂きありがとうございました。
今回の件ですが、
ソースコードは一切改変せず、
DLL側のヒープ領域を5MBに設定することで、解決した模様です。

いまいち原理が理解できていないのですが、
C#とCのDLLは相性があまり良くないということで、自己解決とさせていただきます。

投稿2016/01/27 06:19

rtKikuchi

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんにちは。

ヒープ領域がデフォルトで1MBらしく、それが不足しているのでは?思いましたが、設定方法がいまいちわかりません。

恐らくこの辺の話と思います。
しかし、「デフォルト1MB」はヒープ領域を拡張する単位の話です。ヒープ領域はメモリが許す限りとこまでも取られます。

C#から呼び出した時はヒープ破壊が発生し、Cから呼び出した時は発生しないのですね?
可能性としては2つあると思います。
①C#からの呼び出しとCからの呼び出しのパラメータが異なり、C#からのパラメータではヒープ破壊する。
②C#とDLL間のインターフェースの過程でヒープが壊れる。

②の可能性は0ではないですが、疑うのは最後の最後で良いと思います。まずは①を疑うべきです。

たかだか20回くらいで発生するのでしたら、dll関数側にパラメータをダンプする機能を仕込んでみてはどうでしょうか? dll関数が呼ばれる度にデバッグ用ファイルをアペンド・オープンして出力しクローズすると楽ですよ。(そんな関数を昔は良く作りました。今は最初からログシステムを組み込みますけど。)

Cからの呼び出しの場合と、C#からの呼び出しの場合を比較してみて下さい。恐らく何か異なるのではないかと思います。C#と同じバラメータをCから与えてみるとたぶんヒープ破壊すると思います。
C側でヒープ破壊できたら、この辺を使うと原因追求が楽にできますが、たかだか20回くらいで発生するのなら、デバッガで追いかけても十分かも。

もしかすると、_CrtSetDbgFlag()はC#からも使える可能性はあります。C#でトライしたことはないのですが、C#のメモリ管理(遅延解放)と適合する気がしないので、使えないと予想します。

投稿2016/01/26 10:32

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問