该程序将扫描PGM文件并将其值存储到函数LerPGM()
内动态分配&img
的数组中,然后该函数将返回PGM *imgconv
。在我宣布LerPGM
时,我将imgconv=LerPGM()
分配给它(printf
)。问题是,函数内部的printf("%d ", img.imagem[i][j])
(printf("%d ", imgconv->imagem[i][j])
完美地工作,但main()
内的#include <stdio.h>
#include <stdlib.h>
typedef struct{
int c;
int l;
unsigned char maximo;
unsigned char **imagem;
} PGM;
PGM *LerPGM(char* entrada);
int main()
{
PGM *imgconv;
int i, j;
imgconv=LerPGM("entrada.pgm");
for(i=0; i<imgconv->l; i++){
for(j=0; j<imgconv->c; j++){
printf("%d ", imgconv->imagem[i][j]);
}
printf("\n");
}
return 0;
}
PGM *LerPGM(char* entrada){
PGM img;
char tipo[3];
int i, j;
FILE *arq;
arq = fopen(entrada, "r");
if(arq == NULL){
printf("Arquivo nao encontrado.");
return 0;
}
fscanf(arq, "%s %d %d %d", &tipo, &img.c, &img.l, &img.maximo);
if(strcmp(tipo, "P2")){
printf("O arquivo nao e PGM.");
return 0;
}
img.imagem = malloc(img.l * sizeof(char *));
for(i=0; i<img.c; i++) img.imagem[i] = malloc(img.c * sizeof(char));
if(img.imagem == NULL){
printf("Falha na alocacao de memoria.");
return 0;
}
for(i=0; i<img.l; i++){
for(j=0; j<img.c; j++){
fscanf(arq, "%d", &img.imagem[i][j]);
}
}
fclose(arq);
for(i=0; i<img.l; i++){
for(j=0; j<img.c; j++){
printf("%d ", img.imagem[i][j]);
}
printf("\n");
}
return &img;
}
只打印第一个项目,然后程序停止工作。
{{1}}
答案 0 :(得分:2)
您正在从函数返回指针,但数据在堆栈中。这就是为什么它不起作用。
X * func() {
X data;
return &data; /* <<== this is broken. */
}
在我的情况下func
或LerPGM
返回时,函数中堆栈的数据将被销毁。
修复 - 类似......
PGM *LerPGM(char* entrada){
PGM * img = (PGM*)malloc( sizeof( PGM ) );
char tipo[3];
int i, j;
FILE *arq;
arq = fopen(entrada, "r");
if(arq == NULL){
printf("Arquivo nao encontrado.");
return 0;
}
fscanf(arq, "%s %d %d %d", &tipo, &img->c, &img->l, &img->maximo);
if(strcmp(tipo, "P2")){
printf("O arquivo nao e PGM.");
return 0;
}
img->imagem = malloc(img->l * sizeof(char *));
for(i=0; i<img->c; i++) img->imagem[i] = malloc(img->c * sizeof(char));
if(img->imagem == NULL){
printf("Falha na alocacao de memoria.");
return 0;
}
for(i=0; i<img->l; i++){
for(j=0; j<img->c; j++){
fscanf(arq, "%d", &img->imagem[i][j]);
}
}
fclose(arq);
for(i=0; i<img->l; i++){
for(j=0; j<img->c; j++){
printf("%d ", img->imagem[i][j]);
}
printf("\n");
}
return img;
}
答案 1 :(得分:0)
您正在返回指向本地变量的指针。这是一个指向变量的指针,它会被销毁并在返回时消失。返回后,指向的位置可能包含一些其他数据,与img
变量的先前内容无关。
如果要从函数返回数据,则应在函数外部准备变量并将其传递给函数进行填充:
int LerPGM(char* entrada, PGM *img){
// ....
FILE *arq = fopen(entrada, "r");
if(arq == NULL){
printf("Arquivo nao encontrado.");
return 0; // ERROR
}
// ....
return 1; // SUCCESS
}
int main()
{
PGM imgconv;
int i, j;
if( LerPGM("entrada.pgm", &imgconv) ) {
for(i=0; i<imgconv->l; i++){
for(j=0; j<imgconv->c; j++){
printf("%d ", imgconv->imagem[i][j]);
}
printf("\n");
}
}
else
printf("No data to process.\n");
return 0;
}
或在函数内的堆上分配一个新变量并返回一个指针(然后记得在使用后释放变量):
PGM *LerPGM(char* entrada){
PGM *img = NULL;
// ....
FILE *arq = fopen(entrada, "r");
if(arq == NULL){
printf("Arquivo nao encontrado.");
return NULL; // ERROR
}
// ....
img = malloc(sizeof(PGM));
if(img != NULL)
{
// fill variable *img with data
}
return img;
}
int main()
{
PGM* imgconv;
int i, j;
// ...
imgconv = LerPGM("entrada.pgm");
if(imgconv != NULL) {
for(i=0; i<imgconv->l; i++){
for(j=0; j<imgconv->c; j++){
printf("%d ", imgconv->imagem[i][j]);
}
printf("\n");
}
free(imgconv->subcomponents);
free(imgconv);
}
else
printf("No data to process.\n");
return 0;
}