【问题标题】:Why does realloc() and free() fail in my code?为什么 realloc() 和 free() 在我的代码中失败?
【发布时间】:2014-11-10 03:48:35
【问题描述】:

realloc() 有问题:

int main(int argc, char* argv[])
{
    int* amis;
    int saisie, cpt = 1;

    while(saisie != -1) {
        printf("Entrer les notes -1 pour quitter :");
        scanf("%d", &saisie);
        if (cpt == 1) {
            amis = malloc(sizeof(int));
            if(amis == NULL) {
                printf("amis == NULL");
                exit(0);
            }
        }
        if(saisie != -1) {
           amis = realloc(amis, sizeof (int) + sizeof (amis));
           if(amis == NULL) {
                printf("amis == NULL       cpt= %d", cpt);
                exit(0);
            }
           amis[cpt] = saisie;
           printf("size = %d, saisie = %d, tab = %d \n", cpt * sizeof(int), saisie, amis[cpt]);
           cpt++;
        }
    }
    printf("%d",1==0);

    afficherTab(amis,cpt);
    printf("END\n");

    free(amis);
    return 0;
}

当我使用sizeof(int) * cpt 而不是sizeof(amis) + sizeof(int) 时,为什么realloc() 会导致错误?

free(amis) 在这种情况下也不起作用。

【问题讨论】:

  • sizeof(amis)sizeof(int*)。当使用sizeof(int)*cpt 时,amis[cpt] = saisie; 也超出范围。
  • 在使用前初始化saisie
  • 指向内存块的指针不知道该块有多大。指针只知道内存地址有多大,因此sizeof 指针将始终相同(大多数情况下为 4 或 8)。您必须使用 size_t 变量来跟踪 amis 的大小

标签: c null free sizeof realloc


【解决方案1】:

您遇到的最大问题是您似乎将指针与数组混淆了。如果使用数组,则:

int foo[10];
printf("%zu\n", sizeof foo/ sizeof *foo);//sizeof foo/sizeof(int)

会给你数组的长度,但是指针不是数组。 As I've explained here:

指针不是数组,所以不需要知道大小数组是。指针可以指向单个值,因此指针可以在没有数组的情况下存在。它甚至不关心它指向的内存位于何处(只读,堆或堆栈......无关紧要)。指针除了自身之外没有长度。指针只是...

所以sizeof amis 将始终是相同的值:内存地址的大小(32 位为 4,64 位为 8)。为了解决这个问题,您将不得不自己跟踪分配块的大小:

size_t amis_size = 0;//use this

scanf(" %d",&saisie);//note the space before %d
amis_size += saisie;
amis = realloc(amis, sizeof *amis * amis_size);

等等。
您应该做的其他事情是:初始化变量:

int *amis = NULL,
    saisie = 0;

修复scanf的格式,检查saisie的值是否为负值-1以外...

最后但同样重要的是:exit(0); 表示您正在终止执行,退出状态为 0。0 表示进程没有错误终止,而 mallocrealloc 失败 错误,使用stdlibexit( EXIT_FAILURE );,或者以非零值退出。

在 main 函数返回之前在指针上调用 free 是一件相当没有意义的事情,但是调用 free 是一个好习惯,所以你可以把它留在那里。
但是,请尝试习惯将NULL 分配给您释放的任何指针:

free(amis);
amis = NULL;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    相关资源
    最近更新 更多