动态分配的数组不会在其声明的函数之外打印

时间:2015-10-06 18:17:53

标签: c pointers struct

该程序将扫描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}}

2 个答案:

答案 0 :(得分:2)

您正在从函数返回指针,但数据在堆栈中。这就是为什么它不起作用。

  X * func() {
      X data;

      return &data; /* <<== this is broken. */

  }

在我的情况下funcLerPGM返回时,函数中堆栈的数据将被销毁。

修复 - 类似......

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;
}