【问题标题】:Why does the returned array differ from the array that uses the return value in my program?为什么返回的数组与我的程序中使用返回值的数组不同?
【发布时间】:2021-12-25 15:13:30
【问题描述】:

我有一个程序,我想将一个新元素添加到结构数组中。 在我的 add 函数中它似乎正在工作,但是当我尝试在 main 函数中使用它时,它似乎与最初返回的不同。

我的main.c 是这样的:

int main(void) {
    Recept * receptek;
    int valasztas;
    int *hossz = 0; //A receptek száma.
    receptek = betolt("receptek.txt", &hossz);
    if (receptek != NULL) {
        menu();
        printf("Valasztott opcio: ");
        while(scanf("%d", &valasztas) == 1) {
            if(valasztas == 1) {
                Recept * uj = recept_felvesz(receptek, hossz);
                printf("%dTH VALUE HERE: %s\n", (int)hossz, uj[(int)hossz].nev);
                if(uj != NULL) {
                    printf("Recept sikeresen felveve.\n\n");
                    hossz = (int)hossz + 1;
                } else {
                    printf("Nem sikerult a receptet felvenni.\n\n");
                }
            } else if(valasztas == 2) {

                kiir(receptek, (int)hossz);
            } else if(valasztas == 6) {
                break;
            } else {
                system("cls");
                menu();
                printf("Ervenytelen opcio.\n\n");

            }
            printf("Valasztott opcio: ");
        }
    } else {
        printf("Nem sikerult betolteni a tarolofajlt!\n");
    }
  return 0;
}

我将添加函数 (recept_felvesz) 存储在另一个 .h 文件中。

Recept* recept_felvesz(Recept* receptek, int* hossz) {
    printf("Hossz 1: %d", (int)hossz);
    setbuf(stdin, NULL);
    char bekert_nev[30];
    char bekert_ot[300];
    printf("Add meg a recept nevet: ");
    if(fgets(bekert_nev, 30, stdin))
        bekert_nev[strcspn(bekert_nev, "\n")] = '\0';   //A \n karaktert kicseréli \0-ra
    printf("Add meg a recept osszetevoit: ");
    if(fgets(bekert_ot, 300, stdin))
        bekert_ot[strcspn(bekert_ot, "\n")] = '\0';     //A \n karaktert kicseréli \0-ra.
    system("cls");
    menu();

    Recept uj = {(int)hossz, bekert_nev, bekert_ot};
    receptek = (Recept*) realloc(receptek, ((int)hossz + 1) * sizeof(Recept));
    receptek[(int)hossz] = uj;

    if (receptek == NULL) return NULL;

    FILE *file = fopen("receptek.txt", "a");
    if (file == NULL) return NULL;

    fprintf(file, "\n%s;%s;", bekert_nev, bekert_ot);
    fclose(file);
    printf("\n%dTH VALUE HERE: %s\n", (int)hossz, receptek[(int)hossz].nev);
    return receptek;
}

这是目前的错误输出:

15TH VALUE HERE: 32423
15TH VALUE HERE: ☺
Recept sikeresen felveve.

为什么实际返回值 (32423) 与 main 函数中使用的返回值 () 不同?

编辑:结构Recept 看起来像这样:

typedef struct Recept {
    int azonosito;
    char *nev;
    char *osszetevok;
} Recept;

【问题讨论】:

  • Recept的定义是什么?看起来您正在将指向局部变量的指针存储到 uj 中(然后将其复制到 receptek 并返回给调用者)。无关:您的一些 NULL 指针检查为时已晚,因为您将在检查之前取消引用 NULL 指针。
  • 我在帖子底部添加了结构
  • 您在函数中使用指向局部变量bekert_nev 的指针(char *nev),该变量不再存在。
  • 这看起来很奇怪:receptek[(int)hossz] = uj; 如果hossz 真的是一个指针,那么您的数组可能会得到巨大的值。如果不是指针,为什么定义为int*
  • “在不同的 .h 文件中。”我希望您不要在 .h 文件中定义该函数。那将是非常糟糕的做法。相反,只需将声明放入标题中并将定义放入 .c 文件中。

标签: c pointers return


【解决方案1】:

在此代码内存中,局部变量bekert_nevbekert_ot 在定义它们的范围之外使用(函数recept_felvesz)。它们在堆栈上分配,因此在退出函数recept_felvesz 后,它们的内存可以被其他任何人使用,因为它被认为是未使用的。例如printf可以将其内部变量存储在这个内存块中。

解决此问题的一种方法是使用malloc 函数在全局内存中分配bekert_nevbekert_ot

char* bekert_nev = malloc(30);
char* bekert_ot = malloc(300);

当你将销毁你的主 receptek 数组时,请记住使用 free 函数释放此内存:

Recept* rec = receptek;
for( int i = 0; i < hossz; ++i) {
  free( rec->nev );
  free( rec->osszetevok );
  rec++;
}

或者,您可以将此数组放在 Recept 结构中并直接写入其中

typedef struct Recept {
    int azonosito;
    char nev[30];
    char osszetevok[300];
} Recept;

【讨论】:

    猜你喜欢
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多