malloc関数とfree

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
azahar

malloc関数とfree

#1

投稿記事 by azahar » 5年前

二次元配列の大きさとその値を入力し、各行の和を計算し、その値からなら一次元配列を作っているのですが、プログラムをコンパイルして一番最初に実行する時は正しい回答が得られるのですが、2回目以降おかしな値が出てきます。
freeがちゃんとできていないからかなと思うのですが、一応確保したところは全部解放してるはずだし、どこがおかしいのかわかりません。
動的メモリの確保を最近理解したばっかりで無知ですが、よろしくお願いします。

コード:


#include<stdio.h>
#include<stdlib.h>

int **dmatrix(int nr, int nc) {
  int **mat;
  mat = (int**)malloc(nr*sizeof(int *));
  if (mat == NULL) 
    puts("Failure!! (from (*dmatrix)[nr])");
  else {
    int i, j;
    int *base = (int*)malloc(nr*nc*sizeof(int));
    if (base == NULL)
      puts("Failure!! (from dmatrix[nr][nc])");
    else {
      for (i=0; i < nr; i++)
	mat[i] = base + i*nc;
    }
    free(base);
  }
  return(mat);
}

int *matrix(int n){
  int *arr;
  arr=(int*)malloc(n*sizeof(int));
  if (arr==NULL)
    puts("Failure!! (from(matrix)");
  return(arr);
}
  
void sigma(int **a,int n,int *b){
  int i,j;
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      b[i]+=a[i][j];
    }
  }
}

int main(void){
  int *b;
  //char buf[40];
  int **a;
  int n=0;
  int i,j;
  
  //fgets(buf,sizeof(buf),stdin);
  //sscanf(buf,"%d",&n);
  scanf("%d",&n);
  
  a=dmatrix(n,n);
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      //fgets(buf,sizeof(buf),stdin);
      //sscanf(buf,"%d",&a[i][j]);
      scanf("%d",&a[i][j]);
	}
    }

  b=matrix(n);
  
  sigma(a,n,b);

  printf("b[0]=%d\n",b[0]);

  free(b);

  free(a);

  
  return 0;
}
  


アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: malloc関数とfree

#2

投稿記事 by みけCAT » 5年前

dmatrix関数内でせっかく確保して場所を配列に登録した領域を、
実際に利用する前に開放してしまっているので、
その後の処理で寿命が付きているオブジェクトを使用することになり、未定義動作になります。
dmatrix関数内のfree(base);を削除し、main関数内のfree(a);の直前にfree(*a);を追加するといいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: malloc関数とfree

#3

投稿記事 by かずま » 5年前

正当な修正方法は既に出ているので、
私は邪悪な方法を紹介します。

コード:

#include <stdio.h>  // scanf, printf, puts
#include <stdlib.h> // malloc, free

int **matrix(int nr, int nc)
{
	int i, **mat = malloc(nr * sizeof(int *) + nr * nc * sizeof(int));
	if (mat) {
		mat[0] = (int *)(mat + nr);
		for (i = 1; i < nr; i++) mat[i] = mat[i-1] + nc;
	}
	return mat;
}

int *vector(int n) { return malloc(n * sizeof(int)); }

void sigma(int **a, int nr, int nc, int *b)
{
	int i, j;
	for (i = 0; i < nr; i++)
		for (b[i] = j = 0; j < nc; j++) b[i] += a[i][j];
}

int main(void)
{
	int **a, *b, nr, nc, i, j;
	if (scanf("%d%d", &nr, &nc) != 2) return 1;
	a = matrix(nr, nc);
	if (!a) { puts("matrix alloc faied"); return 2; }
	for (i = 0; i < nr; i++)
		for (j = 0; j < nc; j++)
			if (scanf("%d", &a[i][j]) != 1) return 3;
	b = vector(nr);
	if (!b) { puts("vector alloc failed"); return 4; }
	sigma(a, nr, nc, b);
	for (i = 0; i < nr; i++) printf("b[%d] = %d\n", i, b[i]);
	free(b);
	free(a);
}
実行例

コード:

3 4
1 2 3 4
5 6 7 8
9 10 11 12
b[0] = 10
b[1] = 26
b[2] = 42

返信

“C言語何でも質問掲示板” へ戻る