0

libjpeg を使用して、画像のピクセル データをマトリックスにコピーしようとしています。ポインターに問題があります。助けてください。

問題の概要:int ***pピクセル データを読み取る関数にポインターを渡します。関数内では、要素にアクセスしてp[i][j][k]操作を実行できますが、プログラムで同じことをしようとするとmainクラッシュします。主な機能は次のとおりです。

#include<stdio.h>
#include<stdlib.h>
#include<jpeglib.h>
#include"functions.h"

void main(void)
{
    char * file="a.jpg";
    int ***p;                 // to store the pixel values
    int s[2]={0,0};           // to store the dimensions of the image
    read_JPEG_file(file,p,s); // Function that reads the image
    printf("%d",p[0][0][0]);  // This makes the program crash
}

ファイル functions.h には次のように書かれています。

int read_JPEG_file(char * file, int ***p, int **s)
{
    int i,j;
    //-----------------libjpeg procedure which I got from the documentation------------
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err=jpeg_std_error(&jerr);

    FILE * infile;      /* source file */
    JSAMPARRAY buffer;      /* Output row buffer */
    int row_stride;
    if ((infile = fopen(filename, "rb")) == NULL) 
    {
        fprintf(stderr, "can't open %s\n", filename);
        return 0;
    }

    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, infile);
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);
    row_stride = cinfo.output_width * cinfo.output_components;
    buffer=(*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
    s[0]=cinfo.output_height;
    s[1]=cinfo.output_width;
    p=(int ***)malloc(s[0]*sizeof(int **));
    for (i=0;i<s[0];i++)
    {
        p[i]=(int **)malloc(s[1]*sizeof(int *));
        for (j=0;j<s[1];j++)
        {
            p[i][j]=(int *)malloc(3*sizeof(int));
        }
}

while (cinfo.output_scanline < cinfo.output_height) 
    {
    jpeg_read_scanlines(&cinfo, buffer, 1);
        for ( i=0; i<cinfo.output_width; i++)
        {
             p[cinfo.output_scanline-1][i][0]=(int)buffer[0][0+3*i];
             p[cinfo.output_scanline-1][i][1]=(int)buffer[0][1+3*i];
             p[cinfo.output_scanline-1][i][2]=(int)buffer[0][2+3*i];
         }
    }

printf("%d",p[0][0][0]); // This works just fine
return 0;
}

メモリ割り当てに何か問題があることは知っていますが、何が原因かわかりません。別のテスト プログラムを試してみたところ、500X500X500 整数の長さのメモリ ブロックが正常に割り当てられ、クラッシュすることなくランダムな整数を出力していたので、メモリ不足は問題ではありませんでした。

4

1 に答える 1

0

int ***p は malloc ではありません。彼を read_JPEG_file に送ると、2 番目の変数 int ***p が作成されました。この 2 番目の変数は、read_JPEG_file の末尾で破壊されました。したがって、 read_JPEG_file で p を使用できますが、それだけです。それを解決するには3つの方法があります。1 つ目は、p を返す方が理解しやすいと思います。

 int ***read_JPEG_file(char * file, int ***p, int **s) {
     ...
     return p; 
 }

 int main() {
    ...
    p = read_JPEG_file(file, p, s);
 }

(pを送る必要がなくなりました)

2 番目の方法は、メインで p を malloc してから送信することです。あなたの場合は少し難しいようです。

3 つ目は、メインで p のアドレスを送信することです。(int * * * *p) があります。使うときは注意が必要です。あなたはそのようなことをすることができます:

 int read_JPEG_file(char * file, int ****p, int **s)
 {
     ...
     *p=(int ***)malloc(s[0]*sizeof(int **));
 }

ここで、p の代わりに *p を使用する必要があります。*p は、ポインター p を含む値を意味します。p は int * * * * なので、彼の値は int * * * です。

 int main()
 {
     ...
     read_JPEG_file(file, &p, s);
 }
于 2013-10-03T11:00:44.070 に答える