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

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

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

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

Q&A

解決済

3回答

1430閲覧

C言語でのメモリの解放が出来ません

ain4425

総合スコア19

C

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

0グッド

1クリップ

投稿2018/07/06 05:01

編集2018/07/17 12:41

画像ファイルを読み込んで、いろいろなフィルタをかけて出力するプログラムを動かしていたのですが、画像枚数を4枚から5枚に増やしたところ以下のようなエラーが出てしまいました。

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland image.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Fatal: Error detected (LME1514) Fatal: Error detected (LME1514) Fatal: Error detected (LME1514) Fatal: Error detected (LME1514)

**[LME1514]**を調べてみたところ、どうもメモリの溢れが問題となっているようでした。
どうか助けて頂けると幸いです。


画像にフィルタをかけるプログラム部分は長くなるので省略しますので、読込、出力等の重要部分だけのプログラムをimage.cとして記載します。
上記に付随するヘッダーファイルはppmlib.hとして記載します。

image.c

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#include <time.h> 5#include"ppmlib.h" 6 7int Setting(void); 8void ReadImage(int set); 9void SaveImage(void); 10 11int main(void){ 12 //標準設定パラメータ 13 int set; 14 15 //メモリ確保 16 memory(); 17 18 //標準設定 19 set=Setting(); 20 21 //画像読込 22 ReadImage(set); 23 24 //画像の出力 25 SaveImage(); 26 27 //メモリの開放 28 free(pimage); 29 return 0; 30} 31 32//標準設定 33int Setting(void){ 34 int set_flag; 35 printf("標準設定→1\n"); 36 printf("詳細設定→0\n"); 37 scanf("%d",&set_flag); 38 39 return set_flag; 40} 41 42 43 44//画像の読み込み 45void ReadImage(set){ 46 47 load_color_image(0,1,set); 48 load_color_image(1,2,set); 49 load_color_image(2,3,set); 50 load_color_image(3,4,set); 51 load_color_image(4,5,set); 52 53} 54 55//画像の出力 56void SaveImage(void){ 57 save_color_image(0,""); 58 save_color_image(1,""); 59 save_color_image(3,""); 60 save_color_image(4,""); 61}

ppmlib.h

c

1#include<stdlib.h> 2#include<string.h> 3 4//height[],width[]のMAX画素数 5#define MAX_IMAGESIZE 3000 6//諧調値 7#define MAX_BRIGHTNESS 255 8//階調数(+1) 9#define GRAYLEVEL 256 10//FILEnameの最大長 11#define MAX_FILENAME 256 12//Buffer最大長 13#define MAX_BUFFERSIZE 256 14//画像枚数 15#define MAX_NUM_OF_IMAGES 5 16 17char pimage; 18 19typedef unsigned char (*pimage_type)[MAX_IMAGESIZE][MAX_IMAGESIZE][3]; 20int width[MAX_NUM_OF_IMAGES],height[MAX_NUM_OF_IMAGES]; 21 22 23void memory(void); 24void load_color_image( int n, int no, int set ); 25void save_color_image( int n, char name[] ); 26void copy_color_image( int n1, int n2 ); 27void init_color_image( int n, int red, int green, int blue ); 28 29void memory(void){ 30 pimage_type pimage = (pimage_type)malloc(MAX_NUM_OF_IMAGES * MAX_IMAGESIZE * MAX_IMAGESIZE * 3); 31} 32 33void load_color_image( int n, int no, int set ){ 34 35 char fname[MAX_FILENAME]; 36 char buffer[MAX_BUFFERSIZE]; 37 FILE *fp; 38 int max_gray=0,x,y,col; 39 40 if( no==1 && set==1){ 41 printf("INPUT FILE : white1.ppm\n"); 42 strcpy(fname,"white1.ppm"); 43 } 44 else if( no==2 && set==1){ 45 printf("INPUT FILE : white2.ppm\n"); 46 strcpy(fname,"white2.ppm"); 47 } 48 else if( no==3 && set==1){ 49 printf("INPUT FILE : white3.ppm\n"); 50 strcpy(fname,"white3.ppm"); 51 } 52 else if( no==4 && set==1){ 53 printf("INPUT FILE : white4.ppm\n"); 54 strcpy(fname,"white4.ppm"); 55 } 56 else if( no==5 && set==1){ 57 printf("INPUT FILE : white5.ppm\n"); 58 strcpy(fname,"white5.ppm"); 59 } 60 else{ 61 printf("INPUT FILE : "); 62 scanf("%s", fname); 63 } 64 if ( (fp = fopen( fname, "rb" ))==NULL ){ 65 printf("CAN'T OPEN THE FILE\n"); 66 exit(1); 67 } 68 fgets( buffer, MAX_BUFFERSIZE, fp ); 69 //check P6 70 if ( buffer[0]!='P' || buffer[1]!='6' ){ 71 printf("FILE TIPE WRONG!\n"); 72 exit(1); 73 } 74 width[n] = 0; 75 height[n] = 0; 76 while ( width[n] == 0 || height[n] == 0 ){ 77 fgets( buffer, MAX_BUFFERSIZE, fp ); 78 if ( buffer[0] != '#' ) { 79 sscanf( buffer, "%d %d", &width[n], &height[n] ); 80 } 81 } 82 83 while ( max_gray == 0 ){ 84 fgets( buffer, MAX_BUFFERSIZE, fp ); 85 if ( buffer[0] != '#' ){ 86 sscanf( buffer, "%d", &max_gray ); 87 } 88 } 89 printf("----------------------------\n"); 90 printf("WIDTH :%d\n",width[n]); 91 printf("HEIGHT :%d\n",height[n]); 92 printf("MAX RGB:%d\n",max_gray); 93 printf("----------------------------\n"); 94 if ( width[n] > MAX_IMAGESIZE || height[n] > 95 MAX_IMAGESIZE || 96 max_gray != MAX_BRIGHTNESS ){ 97 printf("SIZE or RGB WRONG!\n"); 98 exit(1); 99 } 100 for(y=0;y<height[n];y++){ 101 for(x=0;x<width[n];x++){ 102 for(col=0;col<3;col++){ 103 pimage[n][x][y][col] = (unsigned char)fgetc( fp ); 104 } 105 } 106 } 107 printf("COMPLETE! ---> image[%d]\n",n); 108 printf("----------------------------\n"); 109 fclose(fp); 110} 111 112 113void save_color_image( int n, char name[] ){ 114 char fname[MAX_FILENAME]; 115 FILE *fp; 116 int x,y,col; 117 if ( name[0] == '\0' ){ 118 printf("OUTPUT FILE : "); 119 scanf("%s",fname); 120 } else strcpy( fname, name ); 121 if ( (fp = fopen(fname, "wb"))==NULL ){ 122 printf("CAN'T SAVE THE FILE\n"); 123 exit(1); 124 } 125 fputs( "P6\n", fp ); 126 fputs( "# Created by Image Processing\n", fp ); 127 fprintf( fp, "%d %d\n", width[n], height[n] ); 128 fprintf( fp, "%d\n", MAX_BRIGHTNESS ); 129 130 for(y=0;y<height[n];y++){ 131 for(x=0;x<width[n];x++){ 132 for(col=0;col<3;col++){ 133 fputc( pimage[n][x][y][col], fp ); 134 } 135 } 136 } 137 fclose(fp); 138 printf("COMPLETE!\n"); 139} 140 141 142void copy_color_image( int n1, int n2 ){ 143 int x,y,col; 144 145 width[n2] = width[n1]; 146 height[n2] = height[n1]; 147 for(y=0;y<height[n1];y++){ 148 for(x=0;x<width[n1];x++){ 149 for(col=0;col<3;col++){ 150 pimage[n2][x][y][col] = pimage[n1][x][y][col]; 151 } 152 } 153 } 154} 155 156 157void init_color_image( int n, int red, int green, int blue ){ 158 int x, y; 159 160 for(y=0;y<height[n];y++){ 161 for(x=0;x<width[n];x++){ 162 if (red != -1) pimage[n][x][y][0] = red; 163 if (green != -1) pimage[n][x][y][1] = green; 164 if (blue != -1) pimage[n][x][y][2] = blue; 165 } 166 } 167}

以上よろしくお願いします

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

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

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

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

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

ttyp03

2018/07/06 07:11

質問タイトルと内容が一致してないので修正お願いします。
guest

回答3

0

こんにちは。

LME1415で検索するとグローバル変数とメモリについてがでてきました。
グローバル変数を取りすぎるとリンクエラーになるようです。

unsigned char image[MAX_NUM_OF_IMAGES][MAX_IMAGESIZE][MAX_IMAGESIZE][3];

のバイト数を計算すると530003000*3=135,000,000=0x80BEFC0となり、BCCがサポートしているグローバル領域のサイズを超えているっぽいです。

これくらい大きなメモリはヒープに獲得(malloc/free等を使う)した方がよいと思います。

投稿2018/07/06 05:18

Chironian

総合スコア23272

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

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

ain4425

2018/07/16 05:12

返信が遅くなり申し訳ありません。 mallocを使おうと思ったのですが、どうも理解が追いつきません。 一行で済むようなものなのでしょうか?
Eki

2018/07/16 06:01 編集

雑にやるなら unsigned char *image = malloc(MAX_NUM_OF_IMAGE * MAX_IMAGEIZE * MAX_IMAGEIZE * 3); とすればよさそうですが、これは一次元配列なのでインデックスアクセスが面倒になります (掛けたり足したりして調整しないといけない) 。それが嫌なら typedef unsigned char (*pimage_type)[MAX_IMAGEIZE][MAX_IMAGEIZE][3]; pimage_type pimage = (pimage_type)malloc(MAX_NUM_OF_IMAGE * MAX_IMAGEIZE * MAX_IMAGEIZE * 3); とキャストする手もあります。ただし C 言語ではこういう「一見できそうなこと」をすると往々にして未定義動作だったりしちゃうので、そのあたりは少し詳しい方を待ちます... malloc() したら、使い終わったときに free() するのをお忘れなく。
Chironian

2018/07/16 09:55

ain4425さん、Ekiさんが書かれている内容で良いと思いますよ。typedefのやり方でも問題ないはずです。
ain4425

2018/07/17 09:52

Ekiさん、Chironianさん ありがとうございます。一次元配列は今後いろいろな機能を追加していくときに不便になるかと感じたため、typedefの方法を使用させていただきたいと考えました。 ヘッダファイルの変数定義部分を少し書き換えましたが、free()を使って開放することができません。 free(pimage); を使用後に入れればよいのでしょうか? 使用しているのは主にimage.cなのですが、そのままmain関数に含めてはまずいですよね? 以上長くなりましたがお聞きしたいです。すみません。
Chironian

2018/07/17 10:25

> ヘッダファイルの変数定義部分を少し書き換えましたが、free()を使って開放することができません。 > free(pimage); を使用後に入れればよいのでしょうか? もし、やってないならやってみましょう。 その結果、期待通り動かないようでしたら、「◯◯となることを期待したけど、△△となります。どうすれば◯◯にできるでしょうか?」的な質問をすると好ましいですよ。
ain4425

2018/07/17 10:43

そうですね、すみません。 実行してみたところ、 エラー E2063 ppmlib.h 18: 不正な初期化 エラー E2451 ppmlib.h 96: 未定義のシンボル image(関数 load_color_image ) エラー E2451 ppmlib.h 126: 未定義のシンボル image(関数 save_color_image ) エラー E2451 ppmlib.h 143: 未定義のシンボル image(関数 copy_color_image ) エラー E2451 ppmlib.h 155: 未定義のシンボル image(関数 init_color_image ) というエラーが出てきてしまいました。 freeのところでのエラーが出ると思いきや、今まで通っていた部分のエラーでした。 これは何が原因なのでしょうか?
Eki

2018/07/17 10:47

もしかして変数宣言のところに直接 malloc() を書いていませんか? 変数宣言ではポインタを宣言するにとどめ、malloc() を実行する関数を別に用意しましょう。 同様に free() を実行する関数も自分で用意し、後で呼び出す必要があります。 このへんが面倒ですよね...
ain4425

2018/07/17 11:16

Ekiさん その通りでした。 新たにfree()とmalloc()を追加してみましたが、エラーが多すぎてどこか根本的に間違えてしまいました。 pimage含め、あまりよく分かっておりません。 エラーの中に エラー E2356 ppmlib.h 20: 'malloc' の再宣言で型が一致していない という項があるのですが、再宣言の指すものがよくわかりません。お願いします。
Chironian

2018/07/17 11:27

> void free(void){ > free(pimage); >} これは駄目ですよ。C言語は同じ名前の別の関数を定義しては行けません。
Eki

2018/07/17 11:29

malloc() と free() は stdlib.h で提供される標準ライブラリ関数です。そこに自分で malloc() という別の関数を定義しようとしているので、コンパイラは混乱してしまっています。エラーは直接的には「以前に宣言されている malloc() と違う引数・戻り値で再宣言してしまっているよ」と言っています。実際の問題は malloc() を呼び出す関数の名前を malloc() にしちゃって衝突していることですね。 Chironian さん、回答のコメント欄に割り込むようなことをしてすみません。
ain4425

2018/07/17 11:42

Chironianさん、Ekiさん ライブラリ関数であるということを失念していました。 書き直したところ、先ほどの大量のエラーが3割ほどに減りました、ありがとうございます。 今現在、 警告 W8004 ppmlib.h 28: 'pimage' に代入した値は使われていない(関数 memory ) エラー E2451 ppmlib.h 100: 未定義のシンボル image(関数 load_color_image ) エラー E2451 ppmlib.h 130: 未定義のシンボル image(関数 save_color_image ) エラー E2451 ppmlib.h 147: 未定義のシンボル image(関数 copy_color_image ) エラー E2451 ppmlib.h 159: 未定義のシンボル image(関数 init_color_image ) エラー E2188 image.c 16: 式の構文エラー(関数 main ) エラー E2451 image.c 28: 未定義のシンボル pimage(関数 main ) となりましたが、pimageの組み込み方がやはり違うのでしょうか。 voidとしてしまいましたがここが問題でしょうか? よろしくお願いします
Eki

2018/07/17 12:06

順番にエラーを読んでいきましょう。 「エラー」とは文法上の間違いのことをいいます。コンパイラはそのプログラムを読み解こうとしたのですが、コードのどこかが間違っているため分からなかったということです。 「警告」とは、プログラムの文法上の間違いではないですが、「本当にそれでいいんですか?」と心配してくれているものです。最初の警告は、「せっかく pimage にメモリを確保したのに、何もしないまま捨ててしまってるけど?」と心配してくれています。よく見ると pimage をローカル変数にしてしまっていますよね。これでは pimage は関数を終了すると破棄されてしまい、せっかく確保したメモリにアクセスする方法がなくなってしまいます。それでいいですか? 全然良くないですね。解決しましょう。方法としては pimage をグローバル変数にするか、 memory() 関数の戻り値として pimage を返し、 pimage を必要とする関数に引数で渡すか、そのどちらかになると思います。 次はいくつか同じエラーです。文法的なミスです。それぞれ「image なんてものは知らない」と言っています。確かにもう image はないですね。今は pimage という名前にしてしまいました。 次もエラーです。関数の宣言では、その関数が引数をとらないことを表すのに void というものが必要です (これは歴史的な経緯です) 。が、実際に呼び出すときには void と書いてはいけません。 次もエラーです。これの原因は最初の警告のところで説明した通りです。
ain4425

2018/07/17 12:46

Ekiさん 返信ありがとうございます、とても分かりやすいです。 今回はグローバル変数を使用することにしました。 そこで1つつまずいてしまったのですが、pimageというのはchar型ではないのでしょうか? ヘッダファイルに char pimage; の一行を追加しましたが、現在以下の警告とエラーが表示されます。 警告 W8004 ppmlib.h 31: 'pimage' に代入した値は使われていない(関数 memory ) エラー E2062 ppmlib.h 103: 無効な間接参照(関数 load_color_image ) エラー E2062 ppmlib.h 133: 無効な間接参照(関数 save_color_image ) エラー E2062 ppmlib.h 150: 無効な間接参照(関数 copy_color_image ) エラー E2062 ppmlib.h 150: 無効な間接参照(関数 copy_color_image ) エラー E2062 ppmlib.h 162: 無効な間接参照(関数 init_color_image ) エラー E2062 ppmlib.h 163: 無効な間接参照(関数 init_color_image ) エラー E2062 ppmlib.h 164: 無効な間接参照(関数 init_color_image ) エラー E2342 image.c 28: パラメータ '__block' は void * 型として定義されているので int は渡せ ない(関数 main ) エラー内容が先ほどと変わりましたが、ポインタが問題になっているのでしょうか? 以上よろしくお願いします
Eki

2018/07/17 13:58 編集

malloc() は、ヒープ領域に指定されたサイズのメモリを確保し、そのメモリ領域へのアドレスを返します。 私たちはそのアドレスを経由で確保された領域にアクセスできるわけですね。 ということで、そのアドレスをどこかに保存しておく必要があります。その保存場所というのが pimage です。ですから pimage は char 型ではなく、ポインタ型です。具体的な型はしばらく前に示した pimage_type 型です。 malloc() をどのように使うかについて詳しい解説が必要なら、 https://programming-place.net/ProgrammingPlacePlus/c/035.html などを参照されてはいかがでしょうか。ポインタについての理解がそもそも怪しければ、このサイトの別の章に詳しい説明があります (こちらのサイトはインターネットで見られるものとしては非常に体系的に整えられていると思います。作者さんに感謝です) 。
ain4425

2018/07/17 14:55

サイトを参考にさせていただき、ポインタ型をどう扱うかを学ぶことが出来ました。 おかげさまで一つのキーとなるエラー(E2342)を減らすことが出来ました。 しかし、やはりまだよく残りのエラー、警告の理由が分かりません。 警告 W8004 ppmlib.h 31: 'pimage' に代入した値は使われていない(関数 memory ) エラー E2062 ppmlib.h 103: 無効な間接参照(関数 load_color_image ) エラー E2062 ppmlib.h 133: 無効な間接参照(関数 save_color_image ) エラー E2062 ppmlib.h 150: 無効な間接参照(関数 copy_color_image ) エラー E2062 ppmlib.h 150: 無効な間接参照(関数 copy_color_image ) エラー E2062 ppmlib.h 162: 無効な間接参照(関数 init_color_image ) エラー E2062 ppmlib.h 163: 無効な間接参照(関数 init_color_image ) エラー E2062 ppmlib.h 164: 無効な間接参照(関数 init_color_image ) どこが問題でどうすればよいのか教えていただけると幸いです。
Chironian

2018/07/17 15:31

ああ、気がつくとずいぶん伸びてました。 Ekiさん、折角ここまでサポートされているので回答を起こされた方が BA を適切につけることができて好ましいと思いますよ。
Eki

2018/07/17 16:25

現在どのようなコードになっているのか少し分からないのですが、とりあえず、 E2062 の原因は pimages の型にあると思われます。今質問文に掲載されているコードだと、 pimages の型が char になっています。もしこのままなら、 char に対してインデックスアクセス pimages[...] はできませんから、それでエラーになっていると思われます。 そうですね。今までのことも含めて回答のまとめようかと思います。
guest

0

ベストアンサー

Chironian さんのコメント欄でお話していましたが、あまりにも長くなってきたので、まとめる意味を込めてこちらに回答します。

しばらく、既にコメント欄で進めて解決した部分も含めてまとめていきます。
説明の都合上変更したところがあります。特に pimage_type を廃止したので注意です (別の型を導入しました) 。 pimage_type のことは一旦忘れてください。

malloc() と free()

まず最初の問題は、グローバル変数として確保しようとしている多次元配列が非常に大きかったため、コンパイラの限界を越えてしまったことでした。そのような大量のメモリ確保を行うときは、残念ながら ヒープ領域 に頼る他ありません。ヒープ領域は malloc() 関数を使って確保するメモリ領域です。ここでは一般により多くのメモリを確保することができますが、若干速度が遅くなったり、使い終えた領域を忘れずに free() しなければいけなかったりと少し不便な領域です。

さて、例えば malloc() を使って int 型の要素数 10 の配列を確保するには、次のようにします。

c

1// malloc() は取得したい領域のサイズをバイト単位で受け取ります。 2// sizeof(int) は int 1 つ分のバイト数を表すので、それ×10 をしてやれば 10 個分になりますね。 3int *p = (int *)malloc(sizeof(int) * 10); 4 5// なんかいろいろ。 int のポインタは厳密には一次元配列ではありませんが、 6// 似たような扱いができます。 p[0] のように添字でアクセスできます。 7p を使う処理1; 8p を使う処理2; 9p を使う処理3; 10 11// 終わったら、必ず解放しましょう。 12free(p);

malloc() は言われた通りのサイズの領域をガバッと持ってくることしかしませんから、確保したメモリ領域がどういう型を格納するためのものかなどは気にしません。上の例では、わたしたちは確保した領域を int の配列として使いたかったのですよね?ということで、確保した領域を int のポインタにつっこんでいるのです。

多次元配列の malloc()

さて、多次元配列のときはどうしましょうか。実は、C言語には多次元配列というものはなく 配列の配列 しかないのです。ということは配列の型が分かれば、上の例と同様に、その配列の型へのポインタにつっこめば配列の配列として使えるのではないでしょうか?

はい、実は配列にも型があります。ただし表記が複雑なので混乱します。これはC言語の悪いところの一つですが、興味があれば聞いてください。説明します。が、もう少し後でもよいかもしれません。

とりあえず次の一文で、 image_type という名前が、とある配列へのポインタ型になります。

c

1typedef unsigned char image_type[MAX_IMAGESIZE][MAX_IMAGESIZE][3];

さきほどまでコメント欄では pimage_type としていましたが、 名前も内容も 僅かに変わっています。混乱させてすみません。

この image_type がどういう型かですが、

c

1unsigned char image[MAX_NUM_OF_IMAGES][MAX_IMAGESIZE][MAX_IMAGESIZE][3]; 2image_type image[MAX_NUM_OF_IMAGES];

上の二つの宣言が全く同じものになるような型です。よく見ると上の配列は最初にグローバル変数で配列を用意しようとしていたときのアレですね。
感覚的に言えば、上の配列の 3 次元配列部分 [MAX_IMAGESIZE][MAX_IMAGESIZE][3] をひとまとめにしたような型です。

欲しい型が判明してしまえば、やることは int の配列を用意したときと同様です。int だったところを image_type にすればよいです。

c

1image_type *pimage = (image_type *)malloc(sizeof(image_type) * MAX_NUM_OF_IMAGES);

実はコメントにおける pimage_type というのは、 image_type のポインタ型でした。つまり pimage_type == (image_type *) です。 image_type を定義したほうが説明しやすく、分かりやすいと思ったので変更しました。

その後、 malloc()直接グローバル変数の初期値としてつっこむことはできない という話をしましたね。
必ず何か関数を用意して (main() 関数でもよいですが) 実行時の処理 として malloc() しないといけません。同様に free() もどこかしらで行う必要があります。


(イマココ) ここまでコメント欄でお話しました。


いろいろな場所から使えるようにする

そういうわけで実装してくださった memory() 関数ですが、今度は他の場所で pimage が見つからなくなったということでした。
memory() 関数内のローカル変数として宣言されたものは当然、他の関数からは見えません。
別の関数で malloc() するなら、確保したメモリ領域を memory() 関数の戻り値として返してあげるか、 pimage をグローバル変数にするか、どちらかの方法で外に出してやらないといけません。

グローバル変数にするということなので、単純に pimage をグローバルで宣言してやればよいです。 pimage はよくわからない image_type * などという型をしていますが、ただのポインタです。 int * とかと同じでいいんです。

c

1image_type *pimage; 2 3// (中略) 4 5void memory(void) { 6 // memory() 側ではローカル変数 pimage を宣言するのをやめ、グローバル変数につっこむようにする。 7 pimage = malloc(...); 8}

まとめ

結局、次のような感じのコードになります。

c

1typedef unsigned char image_type[MAX_IMAGESIZE][MAX_IMAGESIZE][3]; 2image_type *pimage; 3 4// (中略) 5 6void memory(void){ 7 pimage = (image_type *)malloc(sizeof(image_type) * MAX_NUM_OF_IMAGES); 8}

おまけ

本題とは逸れますが、

  1. printf()FILE 構造体などは stdio.h というヘッダファイルに入っています。できれば #include <stdio.h> しておいたほうがよいと思います。

  2. ReadImage() 関数の定義のところで、その引数のところが

    void ReadImage(set) { // ... }

    となっていますが、きちんと set の型を明示するべきです。コンパイルエラーにはならないのですが、C言語では何も書かないと勝手に int と思われるという恐ろしいルールがあります。今回は set の型は使われ方から見ても int なので結果的に問題はなかったのですが、思わぬバグの温床になります。見た目にもわかりづらいので、例え int を受け取るのであろうと、きちんと書くべきです。

投稿2018/07/17 16:48

編集2018/07/18 05:56
Eki

総合スコア429

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

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

ain4425

2018/07/18 03:46

長く付き合って下さり、本当にありがとうございました。 ヒープ領域について、またポインタなど数々お世話になりました。 結果的にエラー無く通すことが出来ました。まだまだ学ばなければならないことが多いので、Ekiさんに教えてくださったサイトを参考に勉強していこうかと思います。 この度はありがとうございました。
guest

0

静的領域のサイズオーバーではないでしょうか。リンカのオプションでサイズを拡大できるかもしれません。あるいはimageをヒープ領域に確保しましょう。

投稿2018/07/06 05:32

tatamyiwathy

総合スコア1039

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問