2016-04-13 8 views
0
// 
// 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 края detection.I использовать Xcode, чтобы запустить этот код, он всегда подскажет «Тема 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0)» или «Function вызов Аргумент - это неинициализированное значение «at» fread (& image [i] [j], 1,1, fp) ». Почему я использовал статические двумерные массивы, ошибок нет, но динамический двумерный массив является ошибкой?Указатель кода C

ответ

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, из этой функции выделяется память и инициализируется.

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-массив прочитайте один 2D-массив из fp. Вы можете пропустить цикл.

+0

Я использовал этот способ в Visual Studio и получил следующее: IntelliSense: выражение должно быть указателем на полный тип объекта –

+0

@MichaelZhan Для компиляции вам необходимо использовать современный стандартный компилятор C. Компилятор Visual Studio «2015» полностью устарел, он содержит технологию 1989 года, смешанную с технологией 1999 года. – Lundin

+0

HAHA. Наконец, я использовал функцию calloc. И на самом деле, мне нравится Xcode, чтобы написать код. –