besty 0 Posted January 4, 2011 Report Share Posted January 4, 2011 Boas, estou aqui com uns problemas que me está a deixar louco Então e o seguinte. O programa consiste em ler uma imagem .pgm e detectar as arestas da mesma. Para ler a imagem, e para criar uma nova, estou a utilizar um ficheiro pgm.h que o professor disponibilizou. Este ficheiro tem uma estrutura de dados. typedef struct { int height; int width; int max_gray; int *image; } PGMData; e estas duas funções: PGMData* readPGM(const char *filename, PGMData *data); void writePGM(const char *filename, const PGMData *data); No main tenho isto: PGMData picture; readPGM("Original.pgm",&picture); printf("%d altura, %d largura", picture.height, picture.width); Nesta primeira parte só quero consultar os dados da estrutura, mas o que acontece é, simplesmente, um segmentation fault. Não consigo perceber. Deixo a função readPGM para ser mais fácil a ajuda: PGMData* readPGM(const char *filename, PGMData *data) { FILE *pgmFile; char version[3]; int i, j; int lo, hi; pgmFile = fopen(filename, "rb"); if (pgmFile == NULL) { perror("Cannot open file to read"); exit(EXIT_FAILURE); } fgets(version, sizeof(version), pgmFile); if (strcmp(version, "P5")) { fprintf(stderr, "Wrong file type!\n"); exit(EXIT_FAILURE); } SkipComments(pgmFile); fscanf(pgmFile, "%d", &data->width); SkipComments(pgmFile); fscanf(pgmFile, "%d", &data->height); SkipComments(pgmFile); fscanf(pgmFile, "%d", &data->max_gray); fgetc(pgmFile); data->image = (int *)malloc(data->height*data->width*sizeof(int)); if (data->max_gray > 255) for (i = 0; i < data->height; ++i) for (j = 0; j < data->width; ++j) { hi = fgetc(pgmFile); lo = fgetc(pgmFile); data->image[i*data->width+j] = (hi << 8) + lo; } else for (i = 0; i < data->height; ++i) for (j = 0; j < data->width; ++j) { lo = fgetc(pgmFile); data->image[i*data->width+j] = lo; } fclose(pgmFile); return data; } Agradecia a ajuda. Link to post Share on other sites
bubulindo 102 Posted January 5, 2011 Report Share Posted January 5, 2011 O ficheiro pgm.h e pgm.c foram disponibilizados pelo professor? Ou só o .h e tu é que fazes as funcões? Normalmente o segmentation fault tem a ver com apontadores/enderecos de memória... comecaria por ver a lógica disso... O que é feito com a PGMData que envias para a funcão read? Inicializaste-a? Depois não percebo porque alocas memória só para a parte da imagem na estrutura, quando podias alocar espaco para a estrutura toda que te devolveria um apontador de estrutura e não para um inteiro que depois tentas focar como a morada do inteiro na estrutura. Isto soa super esquisito... ora vê se faz sentido, typedef struct { int height; //morada 300 int width; //morada 302 int max_gray; //morada 304 int *image; //morada 306 } PGMData; Depois quando fazes o malloc, dizes que a morada 306 passa a ser morada 694, suponhamos... Isto não me parece que funcione. No entanto, se alocasses o espaco para a estrutura inteira não encontrarias este problema... porque convenhámos, se vais abrir uma imagem que poderá em casos extremos ter 75 Mb, alocar mais 3 inteiros não te vai fazer mossa no sistema, né? O mesmo se passa numa imagem de 1 kB... LOL include <ai se te avio> Mãe () { } Link to post Share on other sites
besty 0 Posted January 5, 2011 Author Report Share Posted January 5, 2011 O ficheiro pgm.h é disponibilizado pelo professor, aquela função readPGM está no ficheiro pgm.h. O que eu fiz no main.c fui inicializar um dado do tipo PGMdata, neste caso picture, e chamar a função readPGM. O que eu acho q a função readPGM faz é extrair os dados da imagem q eu quero ler. (alturar, largura, o tom de cor mais alto, e os pixeis) O que eu quero fazer agora com estes dados, agora inicialmente, é simplesmente fazer um printf. O que a acontece é que ele me dá um segmentation fault e eu não percebo porquê. Link to post Share on other sites
besty 0 Posted January 5, 2011 Author Report Share Posted January 5, 2011 Bem, parece que agora consigo consultar os dados da estrutura sem dar segmentation fault. Continuo é a ter o problema do segmentation fault, noutra parte do programa, e acho que o problema todo veio daqui. Preciso de passar de um array unidimensional para um array 2D, para isso escrevi este código. int main(){ int i,j; int **bipic; PGMData pic; readPGM("Original.pgm",&pic); printf("Altura: %d , largura: %d \n",pic.height,pic.width); bipic=(int **)malloc(pic.height*pic.width*sizeof(int)); for (i=0;i<pic.height;i++) for(j=0;j<pic.width;i++) bipic[i][j]=pic.image[i*(pic.width-1)+j]; free(bipic); return 0; } Mas parece que os limites dos arrays não estão certos. O segmentation fault vem daí ou há mais algum problema no meu código que eu não consigo ver? Link to post Share on other sites
falk0n 0 Posted January 5, 2011 Report Share Posted January 5, 2011 bipic=(int **)malloc(pic.height*pic.width*sizeof(int)); o que tens ali é que estas a declarar um apontador de apontadores e estas a reservar como se fosse apenas um apontador. Deverias fazer int * bipic = NULL; bipic = (int *)malloc(pic.height * pic.width * sizeof(int)); e depois acederes a variável através de "saltos" controlados por ti. int i=0,j=0; for(i=0; i < pic.height ; i++) for(j=0; j < pic.width ; j++) bipic [i*pic.height+j]; ou seja andas a fazer saltos num array "unidimensional" como se fosse "bidimensional". Mas também podes usar o que tu querias antes de um apontador de apontadores. Apenas desta (última forma) tens de controlar a forma como os fazes; int **bipic = (int **)malloc(pic.height * sizeof(int)); int *rows = NULL; int i=0; for(i=0; i < pic.height; i++) bipic[i] = malloc(pic.width * sizeof(int)); Penso que agora é escolher a forma como se quer controlar a informação. Boas programações ps. Se tiver algum erro no código que verifiquem pois isto foi escrito assim de rajada; ps2. Acho que já escrevi código até demais mas como tenho visto em diferentes sitios informações deste genero com o pessoal não "percebe" como controlar os arrays uni e bi dimensionais, achei por bem tentar dar uma ajuda (que talvez tenha sido até demais) por isso peço aos moderadores caso esteja a infringir um bocado do código de conducta que retirem o que achem por bem, Link to post Share on other sites
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now