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

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

ただいまの
回答率

90.51%

  • C

    3687questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 389

ain4425

score 13

画像ファイルを読み込んで、いろいろなフィルタをかけて出力するプログラムを動かしていたのですが、画像枚数を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

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include"ppmlib.h"

int Setting(void);
void ReadImage(int set);
void SaveImage(void);

int main(void){
    //標準設定パラメータ
    int set;

    //メモリ確保
    memory();

    //標準設定
    set=Setting();

    //画像読込
    ReadImage(set);

    //画像の出力
    SaveImage();

    //メモリの開放
    free(pimage);
    return 0;
}

//標準設定
int Setting(void){
    int set_flag;
    printf("標準設定→1\n");
    printf("詳細設定→0\n");
    scanf("%d",&set_flag);

    return set_flag;
}



//画像の読み込み
void ReadImage(set){

    load_color_image(0,1,set);
    load_color_image(1,2,set);
    load_color_image(2,3,set);
    load_color_image(3,4,set);
    load_color_image(4,5,set);

}

//画像の出力
void SaveImage(void){
    save_color_image(0,"");
    save_color_image(1,"");
    save_color_image(3,"");
    save_color_image(4,"");
}

ppmlib.h

#include<stdlib.h>
#include<string.h>

//height[],width[]のMAX画素数
#define MAX_IMAGESIZE   3000
//諧調値
#define MAX_BRIGHTNESS   255
//階調数(+1)
#define GRAYLEVEL        256
//FILEnameの最大長
#define MAX_FILENAME     256
//Buffer最大長
#define MAX_BUFFERSIZE   256
//画像枚数
#define MAX_NUM_OF_IMAGES  5

char pimage;

typedef unsigned char (*pimage_type)[MAX_IMAGESIZE][MAX_IMAGESIZE][3];
int width[MAX_NUM_OF_IMAGES],height[MAX_NUM_OF_IMAGES];


void memory(void);
void load_color_image( int n, int no, int set );
void save_color_image( int n, char name[] );
void copy_color_image( int n1, int n2 );
void init_color_image( int n, int red, int green, int blue );

void memory(void){
    pimage_type pimage = (pimage_type)malloc(MAX_NUM_OF_IMAGES * MAX_IMAGESIZE * MAX_IMAGESIZE * 3);
}

void load_color_image( int n, int no, int set ){

    char fname[MAX_FILENAME];
    char buffer[MAX_BUFFERSIZE];
    FILE *fp;
    int max_gray=0,x,y,col;

    if( no==1 && set==1){
    printf("INPUT FILE : white1.ppm\n");
        strcpy(fname,"white1.ppm");
    }
    else if( no==2 && set==1){
    printf("INPUT FILE : white2.ppm\n");
        strcpy(fname,"white2.ppm");
    }
    else if( no==3 && set==1){
    printf("INPUT FILE : white3.ppm\n");
        strcpy(fname,"white3.ppm");
    }
    else if( no==4 && set==1){
    printf("INPUT FILE : white4.ppm\n");
        strcpy(fname,"white4.ppm");
    }
    else if( no==5 && set==1){
    printf("INPUT FILE : white5.ppm\n");
        strcpy(fname,"white5.ppm");
    }
    else{
        printf("INPUT FILE : ");
        scanf("%s", fname);
    }
    if ( (fp = fopen( fname, "rb" ))==NULL ){
        printf("CAN'T OPEN THE FILE\n");
        exit(1);
    }
    fgets( buffer, MAX_BUFFERSIZE, fp );
    //check P6
    if ( buffer[0]!='P' || buffer[1]!='6' ){
    printf("FILE TIPE WRONG!\n");
        exit(1);
    }
    width[n] = 0;
    height[n] = 0;
    while ( width[n] == 0 || height[n] == 0 ){
        fgets( buffer, MAX_BUFFERSIZE, fp );
        if ( buffer[0] != '#' ) {
            sscanf( buffer, "%d %d", &width[n], &height[n] );
        }
    }

    while ( max_gray == 0 ){
        fgets( buffer, MAX_BUFFERSIZE, fp );
        if ( buffer[0] != '#' ){
            sscanf( buffer, "%d", &max_gray );
        }
    }
    printf("----------------------------\n");
    printf("WIDTH  :%d\n",width[n]);    
    printf("HEIGHT :%d\n",height[n]);
    printf("MAX RGB:%d\n",max_gray);
    printf("----------------------------\n");
    if ( width[n] > MAX_IMAGESIZE || height[n] >
        MAX_IMAGESIZE ||
        max_gray != MAX_BRIGHTNESS ){
        printf("SIZE or RGB WRONG!\n");
        exit(1);
    }
    for(y=0;y<height[n];y++){
        for(x=0;x<width[n];x++){
            for(col=0;col<3;col++){
              pimage[n][x][y][col] = (unsigned char)fgetc( fp );
            }
        }
    }
    printf("COMPLETE! ---> image[%d]\n",n);
    printf("----------------------------\n");    
    fclose(fp);
}


void save_color_image( int n, char name[] ){
    char fname[MAX_FILENAME];
    FILE *fp;
    int x,y,col;
    if ( name[0] == '\0' ){
        printf("OUTPUT FILE : ");
        scanf("%s",fname);
    } else strcpy( fname, name );
    if ( (fp = fopen(fname, "wb"))==NULL ){
        printf("CAN'T SAVE THE FILE\n");
        exit(1);
    }
    fputs( "P6\n", fp );
    fputs( "# Created by Image Processing\n", fp );
    fprintf( fp, "%d %d\n", width[n], height[n] );
    fprintf( fp, "%d\n", MAX_BRIGHTNESS );

    for(y=0;y<height[n];y++){
        for(x=0;x<width[n];x++){
            for(col=0;col<3;col++){
                fputc( pimage[n][x][y][col], fp );
            }
        }
    }
    fclose(fp);
    printf("COMPLETE!\n");
}


void copy_color_image( int n1, int n2 ){
    int x,y,col;

    width[n2] = width[n1];  
    height[n2] = height[n1];
    for(y=0;y<height[n1];y++){
        for(x=0;x<width[n1];x++){
            for(col=0;col<3;col++){
                pimage[n2][x][y][col] = pimage[n1][x][y][col];
            }
        }
    }
}


void init_color_image( int n, int red, int green, int blue ){
    int x, y;

    for(y=0;y<height[n];y++){
        for(x=0;x<width[n];x++){
            if (red   != -1) pimage[n][x][y][0] = red;
            if (green != -1) pimage[n][x][y][1] = green;
            if (blue  != -1) pimage[n][x][y][2] = blue;
        }
    }
}

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ttyp03

    2018/07/06 16:11

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

    キャンセル

回答 3

+5

こんにちは。

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/16 14:12

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

    キャンセル

  • 2018/07/16 15:00 編集

    雑にやるなら

    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() するのをお忘れなく。

    キャンセル

  • 2018/07/16 18:55

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

    キャンセル

  • 2018/07/17 18:52

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

    キャンセル

  • 2018/07/17 19:25

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

    キャンセル

  • 2018/07/17 19: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のところでのエラーが出ると思いきや、今まで通っていた部分のエラーでした。
    これは何が原因なのでしょうか?

    キャンセル

  • 2018/07/17 19:47

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

    キャンセル

  • 2018/07/17 20:16

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

    キャンセル

  • 2018/07/17 20:27

    > void free(void){
    > free(pimage);
    >}

    これは駄目ですよ。C言語は同じ名前の別の関数を定義しては行けません。

    キャンセル

  • 2018/07/17 20:29

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

    Chironian さん、回答のコメント欄に割り込むようなことをしてすみません。

    キャンセル

  • 2018/07/17 20: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としてしまいましたがここが問題でしょうか?
    よろしくお願いします

    キャンセル

  • 2018/07/17 21:06

    順番にエラーを読んでいきましょう。

    「エラー」とは文法上の間違いのことをいいます。コンパイラはそのプログラムを読み解こうとしたのですが、コードのどこかが間違っているため分からなかったということです。
    「警告」とは、プログラムの文法上の間違いではないですが、「本当にそれでいいんですか?」と心配してくれているものです。最初の警告は、「せっかく pimage にメモリを確保したのに、何もしないまま捨ててしまってるけど?」と心配してくれています。よく見ると pimage をローカル変数にしてしまっていますよね。これでは pimage は関数を終了すると破棄されてしまい、せっかく確保したメモリにアクセスする方法がなくなってしまいます。それでいいですか?
    全然良くないですね。解決しましょう。方法としては pimage をグローバル変数にするか、 memory() 関数の戻り値として pimage を返し、 pimage を必要とする関数に引数で渡すか、そのどちらかになると思います。

    次はいくつか同じエラーです。文法的なミスです。それぞれ「image なんてものは知らない」と言っています。確かにもう image はないですね。今は pimage という名前にしてしまいました。

    次もエラーです。関数の宣言では、その関数が引数をとらないことを表すのに void というものが必要です (これは歴史的な経緯です) 。が、実際に呼び出すときには void と書いてはいけません。

    次もエラーです。これの原因は最初の警告のところで説明した通りです。

    キャンセル

  • 2018/07/17 21: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 )
    エラー内容が先ほどと変わりましたが、ポインタが問題になっているのでしょうか?
    以上よろしくお願いします

    キャンセル

  • 2018/07/17 22:56 編集

    malloc() は、ヒープ領域に指定されたサイズのメモリを確保し、そのメモリ領域へのアドレスを返します。
    私たちはそのアドレスを経由で確保された領域にアクセスできるわけですね。
    ということで、そのアドレスをどこかに保存しておく必要があります。その保存場所というのが pimage です。ですから pimage は char 型ではなく、ポインタ型です。具体的な型はしばらく前に示した pimage_type 型です。

    malloc() をどのように使うかについて詳しい解説が必要なら、
    https://programming-place.net/ProgrammingPlacePlus/c/035.html
    などを参照されてはいかがでしょうか。ポインタについての理解がそもそも怪しければ、このサイトの別の章に詳しい説明があります (こちらのサイトはインターネットで見られるものとしては非常に体系的に整えられていると思います。作者さんに感謝です) 。

    キャンセル

  • 2018/07/17 23: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 )
    どこが問題でどうすればよいのか教えていただけると幸いです。

    キャンセル

  • 2018/07/18 00:31

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

    キャンセル

  • 2018/07/18 01:25

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

    そうですね。今までのことも含めて回答のまとめようかと思います。

    キャンセル

checkベストアンサー

+2

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

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

 malloc() と free()

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

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

// malloc() は取得したい領域のサイズをバイト単位で受け取ります。
// sizeof(int) は int 1 つ分のバイト数を表すので、それ×10 をしてやれば 10 個分になりますね。
int *p = (int *)malloc(sizeof(int) * 10);

// なんかいろいろ。 int のポインタは厳密には一次元配列ではありませんが、
// 似たような扱いができます。 p[0] のように添字でアクセスできます。
p を使う処理1;
p を使う処理2;
p を使う処理3;

// 終わったら、必ず解放しましょう。
free(p);

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

 多次元配列の malloc()

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

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

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

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

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

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

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

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

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

image_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 * とかと同じでいいんです。

image_type *pimage;

// (中略)

void memory(void) {
  // memory() 側ではローカル変数 pimage を宣言するのをやめ、グローバル変数につっこむようにする。
  pimage = malloc(...);
}

 まとめ

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

typedef unsigned char image_type[MAX_IMAGESIZE][MAX_IMAGESIZE][3];
image_type *pimage;

// (中略)

void memory(void){
    pimage = (image_type *)malloc(sizeof(image_type) * MAX_NUM_OF_IMAGES);
}

 おまけ

本題とは逸れますが、

  1. printf() や FILE 構造体などは stdio.h というヘッダファイルに入っています。できれば #include <stdio.h> しておいたほうがよいと思います。
  2. ReadImage() 関数の定義のところで、その引数のところが

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/18 12:46

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

    キャンセル

+1

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    OpenCVで動画の読み込みがうまくできません。

    以前別のプログラムで動画の読み込みができましたが、今現在取り組んでいるプログラムではうまくいきません。 言語はC++でopencv2.4.9を使用しています。 Os windo

  • 受付中

    OpenCVで動画の読み込みがうまくできません。

    以前別のプログラムで動画の読み込みができましたが、今現在取り組んでいるプログラムではうまくいきません。   言語はC++を使用しています。  ・ソースコード  ヘッダファ

  • 解決済

    Armadillo-800 EVAで画面の絵をBMP形式で保存したい

    自分はArmadillo-800 EVAとUbuntuでペイントっぽいソフトを作っており、ブラシのサイズ・色の変更、消しゴム、画面クリアの機能を実装することができましたが、タッチパ

  • 解決済

    C# json デシリアライズ Computer Vision api

    jsonデータについて初心者です。 json デシリアライズ はネットサーフィンすると少し出てきますが 深い階層のものがわかりずらく classにする部分などが省略されていたり

  • 解決済

    processingで範囲指定してフレームの保存を行うやり方

    前提・実現したいこと processingでプログラムを組んでいます。 現在、SaveFrameを使って実行結果の画像書き出しを行い、ツールからムービーメーカーで動画にしています。

  • 解決済

    行と列が違う配列の掛け算

    前提 書籍で勉強している学生です。 書籍の2周目をしています。 書籍の解答がないため問題のヒントや解説をしていただけると嬉しいです。 問題 4行3列の行列と3行4列の行列の積を

  • 解決済

    C言語 ファイルからの読み取り

    大学の授業の課題で以下のような問題が出たのですが分かりません。C言語です。 ファイルから読み取る関数と出力する関数を分けたいです。 null 文字を除いて最大20文字を格納でき

  • 解決済

    C言語でファイルを読み込み、一部の要素を取り出すコードのエラー

    前提・実現したいこと c言語でテキストファイルを読み込み、行としてではなく、各要素を読み込んで3列目と4列目だけ出力しようとしています。以下がコード作成のために参考にしているサイト

同じタグがついた質問を見る

  • C

    3687questions

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