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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

1回答

1886閲覧

【C言語】free関数の想定外の挙動によりプログラムが強制的に停止する。

noid

総合スコア3

C

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2021/10/10 18:17

実現したいこと・問題点

一度動的に確保した二次元配列をある時点で全てfree関数で解放し、再度malloc関数によってメモリを確保するプログラムを作ろうとしています。
その際、メモリの状態に依存するとは思うのですが、自分の場合loop:3のp[2]を解放しようとしたところでプログラムがフリーズしてしまいました。
解放しようとしているアドレスは正しいはずで、メモリリークも恐らく起きていないはずです。

実行結果

loop:1 p[0][0]:8C2F48 p[0]:8C2F48 p[0]':0 loop:2 p[0][0]:8C2AA0 p[0][1]:8C2AA4 p[1][0]:8C2AA8 p[1][1]:8C2AAC p[0]:8C2AA0 p[0]':0 p[1]:8C2AA8 p[1]':0 loop:3 p[0][0]:8C2AA0 p[0][1]:8C2AA4 p[0][2]:8C2AA8 p[1][0]:8C2AA8 p[1][1]:8C2AAC p[1][2]:8C2AB0 p[2][0]:8C2AB0 p[2][1]:8C2AB4 p[2][2]:8C2AB8 p[0]:8C2AA0 p[0]':0 p[1]:8C2AA8 p[1]':0 p[2]:8C2AB0

該当のソースコード

C

1#include<stdio.h> 2#include<stdlib.h> 3 4int **malloc2d_int(int,int); 5 6int main(){ 7 int **p; 8 for(int n=1,m=1;n<=100;n++,m++){ 9 printf("\nloop:%d\n",n); 10 11 p=malloc2d_int(n,2); 12 for(int i=0,j;i<n;i++){ 13 for(j=0;j<m;j++){ 14 printf("p[%d][%d]:%X ",i,j,&p[i][j]); 15 } 16 } 17 printf("\n"); 18 19 for(int i=0;i<n;i++){ 20 printf("p[%d]:%X ",i,p[i]); 21 free(p[i]); 22 p[i]=NULL; 23 printf("p[%d]':%X\n",i,p[i]); 24 } 25 free(p); 26 p=NULL; 27 } 28 29 return 0; 30} 31 32int **malloc2d_int(int line,int column){ 33 static int **matrix; 34 int *base_matrix; 35 base_matrix=(int *)malloc(sizeof(int)*line*column); 36 if(base_matrix==NULL){ 37 printf("Error:メモリを確保できませんでした.\n"); 38 exit(1); 39 } 40 matrix=(int **)malloc(sizeof(int *)*line); 41 if(matrix==NULL){ 42 printf("Error:メモリを確保できませんでした.\n"); 43 exit(1); 44 } 45 46 int i; 47 for(i=0;i<line;i++){ 48 matrix[i]=base_matrix+i*column; 49 } 50 51 return matrix; 52}

質問内容

どうすればloop:100まで正常にプログラムを動作させられるのでしょうか。
また原因がfree関数にあるらしいことは分かるのですが、具体的にfree関数でどのような手違いがあったため今回のような事態に陥ってしまったのでしょうか。

試したこと

もともとfree関数のあとにNULLを代入することはしていなかったので、少しでも改善されればと付け加えてみたものの全く効果はありませんでした。
またrealloc関数を使用することも考えてみましたが、その場合メモリリークを起こしやすいと風の噂で聞いたことがあります。
特に今回はメモリの再確保時に変数の値を継承する必要はないので、できる限り上記ソースコードの方向性でいきたいと思っています。

補足情報(FW/ツールのバージョンなど)

開発環境
Visual Studio Code ver. 1.61

実行環境
CPU:Intel Core i5 1.10 - 1.50[GHz]
OS:Windows 10 Home ver. 21H1
メモリ:8.00[GB]
コンパイラ:gcc ver. 6.3.0
コンパイルオプション:-fexec-charset=CP932 -o

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

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

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

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

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

guest

回答1

0

ベストアンサー

c

1 for(int i=0;i<n;i++){ 2 printf("p[%d]:%X ",i,p[i]); 3 free(p[i]);

p[i](iが0以外)をfree()してはいけません。malloc()の戻り値ではないからです。malloc2d_int()では2回しかmalloc()していないのですから、free()する回数も2回だけです。

c

1free(p[0]); 2free(p);

で開放します。開放にループは不要です。

投稿2021/10/10 18:29

編集2021/10/10 18:30
int32_t

総合スコア21695

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

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

noid

2021/10/10 18:41

丁寧なご回答ありがとうございます。 確かに言われてみればそうでした。 free(p[0]); で解放したところ、無事正常に終了しました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問