• ベストアンサー

メモリの解放free()について

noname#20242の回答

noname#20242
noname#20242
回答No.1

一番先頭のポインタはどこかで覚えておく必要があると思います。 そして開放時に下記のような処理でいいのではないでしょうか? item* del_item; top_item = 先頭; while (top_item != NULL) { del_item = top_item; top_item = top_item->right; free(del_item); } 一番先頭のポインタを覚えたくない場合は、item構造体に void* left; を追加して、逆にたどっていけるようにする方法もあります。 item* del_item; while (new_item != NULL) { del_item = new_item; new_item = new_item->left; free(del_item); }

mr_child4
質問者

補足

回答ありがとうございます。 試してみましたが、メモリが増え続けています。 No.2の回答者がおっしゃる通り、全部解放は出来ないんでしょうか。

関連するQ&A

  • 多次元配列のメモリ解放

    多次元配列のメモリ解放についてです。 以下のような方法で多次元配列を確保した場合に、 --- char** ppMain; ppMain = new char*[3]; for (int i = 0; i < 3; i++){ ppMain[i] = new char[20]; } --- メモリ解放する場合、 --- for (int i = 0; i < 3; i++){ delete [] ppMain[i]; ppMain[i] = NULL; } delete [] ppMain; ppMain = NULL; --- で良いでしょうか? おそらく、new/deleteの回数が同じであれば問題ないと思うのですが。 少し混乱してしまって、 delete [] ppMain[i]; によって new char*[3]で確保したところも解放されており delete [] ppMain; が必要なく危険な領域まで解放しようとしているということはないでしょうか? ご専門、お詳しいかたコメント宜しくお願いします。

  • メモリダイナミックアロケーションはメモリをどう管理してるのですか?

    使用PC:東芝TECRA M9 2015MBメモリ、Intel(R)Core(TM)2 Duo CPU 2.50GHz Windows Vista Business 以下のC プログラムで入力データM=3のもとにNの値を3から4へ、4から5へと増加させN=17まで上記PCで正常計算ができた。N=18にしたらWindowsが申し訳ありませんがエラーが起きました。Micorsoft へエラー報告しますか?という例のエラーWindowsが表れて異常計算終了する。 N=18でこのエラーが起きたのでメモリ確保ができなくて異常終了したのだと思います。Windowsでなく、Linuxマシーンで実行させればエラーにならないのでしょうか? //Jensen 2007-11-16作成 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #include <float.h> #define MMAX 24 #define NMAX 25 #define ldmax 100 float d[NMAX+1][NMAX+1]; float point[NMAX][ldmax]; unsigned int NS[MMAX+1]; float dij(int i,int j,int N,int ld); int Makeup_eval(int N,int k,float eval[],int ks); float evaluate(int N,int k,int w[]); int Outputdij(int N,int ld); int Subsets(int N,int K, int k, int tbl[], int ks); int Prepare_Network(int M, int N, short int min[], short int max[]); int main() { unsigned int kk, k; int ks,M,N,K,i,j,ld,dummy,ds,is,stateKm1k; int **state,**trace_back,state_tbl[65536];//33554432=2**NMAX=2**25 needs about 2MB memory which causes difficult error at excution.      //Note that 2**15=65536. short int min[NMAX+1],max[NMAX+1]; float eval[65536; char pbname[101]; clock_t start; float **dpv; FILE *in,*out; in=fopen("InCluster.txt","r"); out=fopen("OutCluster.txt","w"); start = clock(); printf("Time One:%d 秒\n",(clock()-start)/CLOCKS_PER_SEC); fscanf(in,"%s",pbname); fscanf(in,"%d %d %d",&M,&N,&ld); for(i=0;i<N;i++)//N kono data. {//8retsu me no tyuukakko. fscanf(in,"%s",&dummy);// i=0 ya i=1 wo yomitobasu. for(k=0;k<ld;k++)//ld dimension. { fscanf(in,"%f",&point[i][k]); } } //Debug write of point.Start. 2007-12-4, point no debaggu. // for(i=0;i<N;i++) { for(k=0;k<ld;k++)//ld dimension. { printf(" point[%d][%d] = %f",i,k,point[i][k]); } printf("\n"); } // //point no debaggu.End of debug write of point, 2007-12-4. strcat(pbname,"HIK"); fprintf(out,"%s\n",pbname); fprintf(out,"M = %d N = %d ld = %d\n",M,N,ld); fprintf(out,"\n\n"); fprintf(out,"CLUSTERS with Optimal Objctive value"); printf("CLUSTERS with Optimal Objctive value"); if(!((1<=ld)&&(ld<=ldmax))) { printf("Error NO 510"); return 510; } if(!((2<=M)&&(M<=N)&&(N<=NMAX))) { printf("Error NO 520"); return 520; } // //この間にイニシャライゼーション計算部分がありますが全角2000文字以内の制約で省略しました。以下のnew 命令以外の原因が見当たらないのですが、new 命令で大域変数として確保されるのなら2015MBメモリを持つ私のPCがWindowsの原因不明により異常計算終了する理由はなんなのでしょうか? // //ダイナミックアロケーションはC++文法で確保しないと文法エラーになる。// state = new int*[M + 1]; trace_back = new int*[M + 1]; dpv = new float*[M + 1]; for(K = 0;K <= M;K++) { state[K] = new int[NS[K]]; if(!state[K]) { printf("Allocation Error of state[%d].520",K); } } for(K=0;K<=M;K++) { trace_back[K] = new int[NS[K]]; if(!trace_back[K]) { printf("Allocation Error of trace_back[%d].520",K); } } for(K=0;K<=M;K++) { dpv[K] = new float[NS[K]]; if(!dpv[K]) { printf("Allocation Error of dpv[%d].530",K); } }

  • メモリの解放について

    C++でDirectXを用いたゲームを作成しているのですが、プログラムのコンパイルは通るのに、メモリの解放関数が行われると強制終了されエラーメッセージが出力されます。 デバッグをしてみて要因を調べてみましたが、特に強制終了するような問題があるとも思えないのです。(ただ自分の知識不足であると思いますが) ためしにエラーが出ている部分をコメントにしてみたら、そしたらヒープが壊れてるとのエラーメッセージが出るのですがどう対処したらいいでしょうか? ちなみにRELEASEする変数の中身はちゃんと入ってます。 ソース: const int MAXFONT = 16; LPD3DXFONT g_pxfonts[MAXFONT]; LPD3DXSPRITE g_ptextsprite = NULL; int d=0; void DirectGraphics::CleanupD3D(){ //フォント解放 for(d=0; d<MAXFONT; d++){ if(g_pxfonts[d]!=NULL){ g_pxfonts[d]->Release();//エラー } } if(g_ptextsprite) g_ptextsprite->Release();//エラー //メッシュ、テクスチャ解放 for(d=0; d<MAXMODEL; d=d+1){ if(g_models[d].used == TRUE){ if(g_models[d].pmaterials != NULL){ delete[] g_models[d].pmaterials; } if(g_models[d].ptextures != NULL){ for(DWORD j=0; j<g_models[d].nummaterials; j=j+1){ g_models[d].ptextures[j]->Release(); } delete[] g_models[d].ptextures; } if(g_models[d].pmesh != NULL){ g_models[d].pmesh->Release(); } } } if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); } エラーの出ているフォントの変数の中身はこちらに入れております。 //ゲーム用のフォントを作成 int DirectGraphics::CreateGameFont(LPCTSTR fontname, int height, UINT weight){ //空いている要素を探す int idx; for(idx=0; idx<MAXFONT; idx=idx+1){ if(g_pxfonts[idx] == NULL) break; } if (idx>=MAXFONT) return -1; //フォントを作成する HRESULT hr = D3DXCreateFont( g_pd3dDevice, -height, 0, weight, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontname, &g_pxfonts[idx]); if( FAILED( hr ) ) return -1; return idx; }

  • LU分解を利用した逆行列のプログラム(Java)

    LU分解を利用した逆行列のプログラムが作れません… というか、作ったのですが実行するとエラーが出てしまいます(´Д`;) どこをどう直せばいいか、もしくはこのようにプログラムした方が効率がよい などのアドバイスどなたか下さい double a[][]={{2,5,4}, {2,3,-1}, {6,9,28}}; int N=a.length; double[][] s=new double[N][N]; for(int k=0; k<a[0].length-1; k++){ for(int i=k+1; i<N; i++){ s[i][k]=a[i][k]/a[k][k]; a[i][k]=s[i][k]; for(int j=k+1; j<N; j++){ a[i][j] -= s[i][k] * a[k][j]; } } } double[][] y=new double[N][N]; double[][] X=new double[N][N]; double[][] e=new double[N][N]; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ if(i==j){ e[i][j]=1; }else{ e[i][j]=0; } } } for(int i=0;i<N;i++){ y[1][i]=e[1][i]; for(int k=2;k<=N;k++){ for(int j=1;j<=N;j++){ y[k][i]=e[k][i]-s[k][j]*y[j][i]; } } X[N][i]=y[N][i]/a[N][N]; for(int k=N-1;k>=1;k--){ for(int j=k+1;j<=N;j++){ X[k][j]=(y[k][j]-s[k][j]*X[j][i])/a[k][k]; } } } for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ System.out.printf(" %6.5f ", X[i][j] ); } System.out.println(""); }

  • 動的メモリ 解放がうまくいかない

    よろしくお願いします。 一ファイル20万行程度のCSV形式のテキストファイルが、50個ほどあります。 これを一行づつ読み込んで、strtok( ,",")でデータを取得しようと思っています。 ファイルの行数はまちまちなので、新しいファイルを読み込むときに そのファイルの行数を調べて(ここでは count 行あります) callocをつかって、メモリを確保しました。 btxt=(char **)calloc(count,sizeof(char *));/*動的メモリ確保*/ for(i=0;i<count;i++) btxt[i]=(char *)calloc(120,sizeof(char)); /*一行120文字まで*/ if(btxt==NULL){printf("btxt 確保エラー\n"); exit(0);} 上記btxt配列にすべての行数を読み込んで、strtok()処理をした後 for(v=0;v<120;v++){ if(btxt[v]){ free(btxt[v]); btxt[v]=NULL; }  } free(btxt);  btxt=NULL; で解放してから、次のファイルに移ります。 問題は、ループするごとにメモリ容量がどんどん減ってきて、30ループもさせると メモリ不足でエラーが出ることです。 ブレークポイントを使って調べてみたのですが ループ一回目 calloc前 707.7 MB: calloc後 748.6MB 解放(したつもり)後 747.9 MB ループ二回目 calloc前 750.6 MB: calloc後 794.6MB 解放(したつもり)後 793.8 MB ・・・・・・・・・・・・・・・・・・・ ループ四回終了時には868.3MBにもなって、初めより160MBも使ってしまいます。 free()が効いてないと思うのですが、どこがおかしいのか教えてくださいませ。

  • CからVB

    以下のプログラムはC言語で作成されています。 これをVBで作成したいです。 教えてください。 #include <stdio.h> #include <stdlib.h> double *alloc(int r,int n,int m); void input(double *p,int r,int n,int m); void sumup(double *p,int r,int n,int m); int main(void){ int r, n, m; double *p; // 行列サイズ入力 printf("input r n m "); scanf("%d %d %d",&r,&n,&m); // 行列領域取得 p = alloc(r,n,m); // 行列要素入力 input(p,r,n,m); // 行列の和 sumup(p,r,n,m); //終了,行列領域解放 free(p); return 0; } double *alloc(int r,int n,int m){ double *p; printf("MATRIX[r=%d][n=%d][m=%d]\n\n",r,n,m); p = (double*)malloc(sizeof(double)*r*n*m); if( p == NULL){ printf("error! malloc failed.\n"); exit(-1); } return p; } void input(double *p,int r, int n,int m) { int i,j,k; for(i = 0; i < r; i++){ for(j = 0;j < n; j++){ for(k = 0; k < m; k++){ printf("input MATRIX[%d][%d][%d]= ",i,j,k); scanf("%lf",&p[i*(n*m)+j*m+k]); } } } printf("\n"); } // 行列の和 void sumup(double *p,int r,int n,int m){ int i, j, k; // 0.0, not 0!!! double sum = 0.0; printf("sum of %d matrices:\n",r); for(j = 0; j< n; j++){ for(k = 0;k < m; k++){ sum=0; for(i = 0;i < r;i++){ sum += p[i*(n*m)+j*m+k]; } printf("\n%2f",sum); } } printf("\n"); }

  • 3次元配列のループによる比較の回数を減らす

    以下は正の整数が入った3次元配列form[30][20][8]で、中身が一致している2カ所に-1を代入してループを抜けるというプログラムの一部分なんですが、無駄なループを減らすにはどういった変更をすればいいでしょうか? form[30][20][8]は変更しない方向でお願いします。 check: for(int i=0;i<30;i++){ for(int j=0;j<20;j++){ for(int k=0;k<8;k++){ for(int l=0;l<30;l++){ for(int m=0;m<20;m++){ for(int n=0;n<8;n++){ if(form[i][j][k]==form[l][m][n]&&!(i==l&&j==m&&k==n)form[i][j][k]!=-1) count++; form[i][j][k]=-1; form[l][m][n]=-1; break check; } } } } } } }

    • ベストアンサー
    • Java
  • c言語 行列のn階乗のプログラム

      1 2 -1 D= 3 0 -2   -1 1 2 の3次正方行列のn乗を計算するプログラムを作成しています。 いろいろと試してみましたがうまくいきません。 どなたか教えていただけるとうれしいです。 よろしくおねがいします。 #include <stdio.h> int main(void) { int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int s[3][3]; int m,n; int i,j,k; printf("[A]^n;n = ");scanf("%d",&n); for (m=2;m <= n;m++){ for (i=0;i<3;i++){ for (j=0;j<3;j++){ s[i][j] = 0; for(k=0;k<3;k++){ s[i][j] =s[i][j] + a[i][k] * b[k][j]; } } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ b[i][j]=s[i][j]; } } printf("%3d",s[i][j]); putchar('\n'); } return (0); }

  • 0が表示されてしまいます

    次のようなプログラムを作成し、3つの配列の共通部分を表示したいのですが、うまく表示されず0が何個も表示されました。おかしい部分は/**/で囲みましたので、なぜ0が表示されるのかわかる方いましたら教えてください。お願いします。 import java.util.*; import java.lang.*; public class hairetu { public static void main(String[] args) { Random generator = new Random(); int hairetu[] = new int[90]; for(int i=0; i<90; i++) { hairetu[i] = (int)(Math.random() * 450); } int hairetu2[] = new int[90]; for(int i=0; i<90; i++) { hairetu2[i] = (int)(Math.random() * 450); } int hairetu3[] = new int[90]; int k = 0; for(int i=0; i<90; i++) { for(int j=0; j<90; j++) { if(hairetu[i] == hairetu2[j]) { hairetu3[k] = hairetu[i]; System.out.println(hairetu3[k]); k++; } } } System.out.println("\n---------------------------------\n"); int hairetu4[] = new int[90]; for(int i=0; i<90; i++) { hairetu[i] = (int)(Math.random() * 450); } /* int hairetu5[] = new int[90]; int m = 0; for(int i=0; i<90; i++) { for(int j=0; j<90; j++) { if(hairetu3[i] == hairetu4[j]) { hairetu5[m] = hairetu3[i]; System.out.println(hairetu5[m]); m++; } } }*/ } }

    • ベストアンサー
    • Java
  • c言語 ファイル出力について

    このようなプログラムを作成しました。 エクセルでファイルを出力したいのですが… ファイルは作成できたものの、内容が書かれていません。 とても困っています↓ 自分の力不足なのでしょうがどなたかお願いします。 #include <stdio.h> #include <process.h> #define S 256 #define I 100 #define J 100 #define K 3 //グループの数 void sum(int u[][J],int N,int n); void sort(int y[],int N,int u[][J],int n); void group(int num[],int u[][J],int N,int n); void passege(int groupm[][J],int groupn,int u[][J],int n,int N); void main (void) { FILE *fp; int N=0,i=0,j=1,kou=0,n; //N:人数 n:問題数 static int u[I][J]; char buf[S]; //ファイルオープン if ((fp=fopen("data_i2_3.csv","r"))==NULL){ printf("Can't open File\n"); exit(1); } // 問題数のカウント fgets(buf,S,fp); N+=1; while(buf[i]!='\n'){ kou=kou++; i+=1; } for(i=0;i<=kou;i=i+2){ u[N][j]=buf[i]-'0'; j=j++; } n=kou/2+1; // レコードの読み込み while (fgets(buf,256,fp)!=NULL){ N+=1; // 文字型から数値型へ変換 j=1; for(i=0;i<=kou;i=i+2){ u[N][j]=buf[i]-'0'; j=j++; } } sum(u,N,n); fclose(fp); } void sum(int u[][J],int N,int n) { static int y[I]; int i,ii; //学習者iの得点の初期化 for(i=0;i<=I;i++) y[i]=0; //学習者iの得点の計算 for(i=1;i<=N;i++){ for(ii=1;ii<=n;ii++){ y[i]+=u[i][ii]; } } sort(y,N,u,n); } void sort(int y[],int N,int u[][J],int n) { int left,right,i,shift,t,v; static int num[I]; //学習者の番号記憶用変数numの初期化 for(i=0;i<=I;i++) num[i]=0; for(i=1;i<=N;i++) num[i]=i; //シェーカーソート left=0; right=N; while (left<right){ for(i=left;i<right;i++){ if(y[i]>y[i+1]){ t=y[i]; v=num[i]; y[i]=y[i+1]; num[i]=num[i+1]; y[i+1]=t; num[i+1]=v; shift=i; } } right=shift; for(i=right;i>left;i--){ if(y[i]<y[i-1]){ t=y[i]; v=num[i]; y[i]=y[i-1]; num[i]=num[i-1]; y[i-1]=t; num[i-1]=v; shift=i; } } left=shift; } group(num,u,N,n); } void group(int num[],int u[][J],int N,int n) { int groupn,i,j,k=1; //groupn:グループの人数 static int groupm[K][I]; //groupm:グループのメンバー groupn=N/K; for(i=0;i<K;i++){ for(j=0;j<groupn;j++){ groupm[i][j]=num[k]; k+=1; } } passege(groupm,groupn,u,n,N); } void passege(int groupm[][J],int groupn,int u[][J],int n,int N) { FILE *f; int i,j,k=0,l,tt; static int t[I]; //各グループの正解率 double p[K][J],pp=0.0; //初期化 for(i=0;i<K;i++){ for(j=0;j<J;j++){ p[i][j]=0; t[i]=0; } } for(i=0;i<K;i++){ for(j=0;j<groupn;j++){ t[k]=groupm[i][j]; k+=1; } } k=0; for(i=0;i<K;i++){ for(j=1;j<=n;j++){ for(l=0;l<groupn;l++){ tt=t[k]; pp=pp+u[tt][j]; k+=1; } p[i][j]=pp/groupn; pp=0.0; if(i==0) k=0; else k=groupn*i; } k=groupn*(i+1); } //ファイル出力 f=fopen("test1.csv","w"); //確認 putchar('\n'); for(i=0;i<K;i++){ for(j=1;j<=n;j++){ printf("%d群の項目%dの正解率は%fです\n",i,j,p[i][j]); } } //ファイルを閉じる fclose(f); }