Jump to content
besty

Dúvida num segmentation fault

Recommended Posts

besty

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.

Share this post


Link to post
Share on other sites
bubulindo

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 () {

}

Share this post


Link to post
Share on other sites
besty

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ê.

 

Share this post


Link to post
Share on other sites
besty

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?

Share this post


Link to post
Share on other sites
falk0n


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,

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.