Realloc弄乱了我的结构数组

时间:2017-05-13 16:08:48

标签: c pointers struct dynamic-memory-allocation realloc

我正在做一个可以管理动物园信息的学校项目。动物园有区域,它们被保存在一系列结构中。该区域最多有3个邻居区域。程序初始化时,必须读取包含区域信息的文件。它运作得很好。我在结构中加入了 char区3 [10] ,因此我可以保存邻居区域名称,然后使用区域搜索结构数组并将相邻区域保存在结构指针数组( Area * adj 3 )。它工作正常,直到达到6个区域。我找到了问题的根源。 realloc正在搞乱这些价值观。但我现在不知道为什么以及如何解决它。有人能帮我吗?感谢。

struct.h

typedef struct area Area;
struct area{
    char id[10];
    int peso, nadj;

    char areas[3][10];
    Area *adj[3]; ///ponteiros para areas adjacentes
}; 

的main.c

int menu()
{
    int op;

    printf("\n\n1 - Mostrar Areas");
    printf("\n2 - Nova Area");
    printf("\n3 - Eliminar Area");
    printf("\n4 - Terminar");
    do{
        printf("\nOpcao: ");
        fflush(stdin);
        scanf(" %d", &op);
        putchar('\n');
    }while(op<1 || op>4);
    return op;
}

int main(int argc, char** argv) {

    int i, total;
    FILE *f;    ///FICHEIRO COM ÁREAS
    Area *areas = NULL; ///IMPORTANTE ESTAR A NULL PARA FUNCIONAR

    areas = le_fich("zoo.txt", &total);

    do{
        i = menu();
        switch(i){
            case 1: mostrar_areas(areas, total); break;
            case 2: areas = nova_area(areas, &total); break;
            case 3: printf("Funcao por introduzir."); break;
            case 4: printf("Funcao por introduzir."); break;
        }        
    }while(i != 4);

    free(areas);

    return (EXIT_SUCCESS);
}

funcoes.c

Area *nova_area(Area *p, int *total){
    int i, igual;
    Area *novo;
    char nome_area[TAM], nome_areadj[TAM];


    printf("********BEFORE p[1].adj[0]: %s\n", p[1].adj[0]->id);

    novo = realloc(p, ((*total)+1) * sizeof(Area));
    if(novo == NULL){
        printf("Erro na alocacao de memoria.\n");
        return p;
    }

    printf("******** AFTERp[1].adj[0]: %s\n", p[1].adj[0]->id);

    p = novo;   //CASO p TENHA MUDADO DE SITIO DEVIDO AO REALLOC
    *total = *total +1;

    do{
        printf("ID: ");
        scanf(" %10[^\n]", nome_area);

        igual = procura_area(p, nome_area, *total);
    }while(igual);

    strcpy(p[*total-1].id, nome_area);
    printf("Peso: ");
    scanf(" %d", &(p[*total-1].peso));
    do{
        printf("Nadj: ");
        scanf(" %d", &(p[*total-1].nadj));

        if(p[*total-1].nadj >= 4)
            printf("\tNumero de areas adjacentes excedidas.\n");
    }while(p[*total-1].nadj >= 4);

    for(i = 0; i < p[*total-1].nadj; i++){
        do{
                printf("Nome da area adjacente: ");
                scanf(" %10[^\n]", nome_areadj);
        }while(strcmp(nome_area, nome_areadj) == 0);

        p[*total-1].adj[i] = procura_areaAdj(p, nome_areadj, *total);
        //SE A AREA INSERIDA NAO FOR RECONHECIDA (NULL), O NUMERO DE ADJACENCIAS
        //É DIMINUÍDO
        if(p[*total-1].adj[i] == NULL){
//                p[*total-1].nadj -= p[*total-1].nadj; //AQUIIIIIIIIIIIIIIIIII DA ULTIMA VEZ

            p[*total-1].nadj--;
        }
        else if(p[*total-1].adj[i]->nadj < 3 && p[*total-1].adj[i] != NULL){
            atualiza_areas(p, nome_areadj, *total);
        }
        else{
            p[*total-1].nadj = 0;
            p[*total-1].adj[i] = NULL;
            printf("Numero maximo de areas adjacentes alcancado.\n");
        }
    }
//    printf("********DEPOISp[1].adj[0]: %s\n", p[1].adj[0]->id);
    return p;
}

2 个答案:

答案 0 :(得分:0)

改变它

Area * nova_area (Area *p, int *total) 

为:

Area * nova_area (Area **p, int *total)

您正在按值传递Area。您需要传递Area的指针,以便您可以修改并重新分配它。 您还需要更改realloc:

novo = realloc (*p, ((* total) +1) * sizeof (Area));

答案 1 :(得分:0)

已经解决了。当我重新分配指向结构数组的指针时,我丢失了指针内部的指针位置。我的解决方案是:当搜索邻居区域时,我发送索引并轻松管理区域,而不是返回它的指针。所以现在没有丢失任何指针位置。

struct.h

///STRUCT PARA AS AREAS. INCLUI LISTA LIGADA typedef struct area Area; struct area{
    char id[10];
    int peso, nadj;

    char areas[3][10];
    int adj[3]; ///array de indices das areas adjacentes };

funcoes.c

//when searching
int procura_areaAdj(Area *p, char *nome_areadj, int total){
    for(int i = 0; i < total; i++){        
        if(strcmp(nome_areadj, p[i].id) == 0){    //SE ENCONTROU RETORNA O INDICE 
            return i;
        }
    }

    return -1;   //SE NÃO ENCONTROU, RETORNA -1. PARA FUTURAS VALIDAÇÕES
}


//UPDATING ARRAY OF STRUCTURES VALUES
void atualiza_areas(Area *p, char *nome_areadj, int total){
    int i, j;

    if(total == 1)  //NAO EXISTEM ATUALIZACOES NA PRIMEIRA AREA INSERIDA
        ;
    else{
        for(i = 0; i < total; i++){        
            if(strcmp(nome_areadj, p[i].id) == 0){

                j=0;
                while(j < p[i].nadj)
                    j++;

                p[i].nadj++;
                p[i].adj[j] = total-1; //RETURNS LAST AREA INDEX 

            }
        }
    } }