C代码的指针

时间:2016-04-13 09:16:48

标签: c arrays void-pointers bmp

//
//  main.c
//  cbp
//
//  Created by Zhan on 16/4/13.
//  Copyright © 2016年 Zhan. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include<math.h>

#pragma pack(2)

typedef unsigned short int WORD;
typedef unsigned int DWORD;

typedef struct BMP_FILE_HEADER
{
    WORD bType;
    DWORD bSize;
    WORD bReserved1;
    WORD bReserved2;
    DWORD bOffset;
} BMPFILEHEADER;

typedef struct BMP_INFO
{
    DWORD bInfoSize;
    DWORD bWidth;
    DWORD bHeight;
    WORD bPlanes;
    WORD bBitCount;
    DWORD bCompression;
    DWORD bmpImageSize;
    DWORD bXPelsPerMeter;
    DWORD bYPelsPerMeter;
    DWORD bClrUsed;
    DWORD bClrImportant;
} BMPINF;

/*彩色表*/
typedef struct RGB_QUAD
{
    WORD rgbBlue;
    WORD rgbGreen;
    WORD rgbRed;
    WORD rgbReversed;
} RGBQUAD;

int main()
{
    FILE *fp,*fpout;
    BMPFILEHEADER fileHeader;
    BMPINF infoHeader;
    int width, height;
    //WORD c;
    int s;
    float s1,s2;
    unsigned char **image;

    if((fp = fopen("XG.bmp", "rb")) == NULL)
    {
        printf("Cann't open the file!\n");
    }


    fseek(fp, 0, 0);
    fread(&fileHeader, sizeof(fileHeader), 1, fp);
    fread(&infoHeader, sizeof(infoHeader), 1, fp);

    printf("size fileHeader == %ld\n",sizeof(fileHeader));
    printf("size infoHader == %ld\n",sizeof(infoHeader));

    width = infoHeader.bWidth;
    height = abs(infoHeader.bHeight);

    printf("infoHeader.bWidth == %d\n",width);
    printf("infoHeader.bheight == %d\n",height);

    image = (unsigned char **)malloc(sizeof(unsigned char  *) * width);
    image[0] = (unsigned char *)malloc(sizeof(unsigned char ) * width * height);

    //    unsigned char **image1 =(unsigned char**) malloc (width*sizeof(int*));
    //    for(int i=0;i<width;i++)
    //        *image1++=(unsigned char*) malloc (height*sizeof(int));

    fseek(fp,(sizeof(fileHeader)+sizeof(infoHeader)),SEEK_SET);
    for(int i=0;i<width;i++)
    {
        for(int j=0;j<height;j++){
            fread(&image[i][j],1,1,fp); }}      //Memory leak ?
    for(int i=1;i<width;i++){
        for(int j=1;j<height;j++)
        {
            s1=image[i-1][j+1]+2*image[i][j+1]+image[i+1][j+1];
            s1=s1-image[i-1][j-1]-2*image[i][j-1]-image[i+1][j-1];
            s2=image[i-1][j-1]+2*image[i-1][j]+image[i-1][j+1];
            s2=s2-image[i+1][j-1]-2*image[i+1][j]-image[i+1][j+1];
            s=fabs(s1)+fabs(s2);
            if(s>80)
                image[i][j]=255;
            else
                image[i][j]=0;
        }
    }
    if((fpout=fopen("za.bmp","wb"))==NULL){
        printf("cannot open outfile!\n");
        free(image[0]);
        free(image);
        return 0;
    }
    printf("intoWrite\n");
    fwrite(&fileHeader,sizeof(fileHeader),1,fpout);
    fwrite(&infoHeader,sizeof(infoHeader),1,fpout);
    for(int i=0;i<width;i++)
    {
        for(int j=0;j<height;j++){
            printf("forWrite\n");
            fwrite(&image[i][j],1,1,fpout);}}
    //    c = fgetc(fp);
    //    int mi=0,mj=0;
    //    while (!feof(fp))
    //    {
    //        fwrite(&c,1,1,fpout);
    //        mi++;mj++;
    //    c = fgetc(fp);
    //    }
    free(image[0]);
    free(image);
    printf("OK!\n");
    fclose(fp);
    fclose(fpout);
    return 0;
}

这是我的bmp边缘检测代码。我使用Xcode运行此代码,它总是提示“线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)”或“函数调用参数是未初始化的值”在“ fread(&amp; image [i] [j],1,1,fp)“。为什么我使用静态二维数组没有错误,但动态二维数组是错误的?

3 个答案:

答案 0 :(得分:1)

这会将height分配给每个width,您现在应该可以参考image[i][j]

int each = 0;
image = malloc(sizeof(unsigned char  *) * width);
for ( each = 0; each < width; each++) {
    image[each] = malloc(sizeof(unsigned char ) * height);
}

释放将是类似的。

for ( each = 0; each < width; each++) {
    free ( image[each]);
}
free ( image);

答案 1 :(得分:0)

image[0] = (unsigned char *)malloc(sizeof(unsigned char ) * width * height);

您只为一个数组分配空间,而不是整个查找表,其中每个指针都指向一个已分配的数组。

但首先绝对不需要使用一些模糊的查找表。相反,使用2D数组:

width = ...;
height = ....;
unsigned char (*image)[][height];
image = malloc( sizeof(unsigned char[width][height]) );

...

free(image);

现在,由于你有一个真正的2D数组而不是一些碎片的东西,如果你愿意,你可以一次读取整个数组:

fread(image, sizeof(unsigned[width][height]), 1, fp);

含义:进入我的2D数组,从fp读取一个2D数组。你可以跳过循环。

答案 2 :(得分:0)

image=(WORD **)calloc(width,sizeof(WORD*));
        if (NULL==image) return 1;
            for (a=0;a<width;a++) {
                image[a]=(WORD*)calloc(height,sizeof(WORD));
                if (NULL==image[a]){
                    printf("free image\n");
                    free(image);
                    return 2;}
            }

我使用了calloc函数,这个函数是分配内存并初始化。