realloc()有任何限制吗

Che*_*bim -1 c

在这里,我试图编写一个代码,通过操作字符串来找到2的幂.我知道这可以通过一些内置函数完成,但我有兴趣使用字符串操作技术.

问题工作正常,直到2 76,然后我不知道为什么我的程序显示一些不需要的字符.我不明白为什么这恰好来自指数76,在此之前我得到了所需的输出.

这是我的代码.希望我能找到你的帮助有什么问题.


代码:

注意:这里我使用了4个函数

  1. int len() :找到字符串的长度.
  2. void add() :执行操作以查找2的幂.
  3. void rev() :以相反的顺序显示字符串,作为所需的输出.
  4. int main()
    #include <stdio.h>
    #include <stdlib.h>

    char *a;
    int i;

    int len()
    {
        for(i=0;a[i]!='\0';i++);
        return i;
    }

    void rev()
    {
        printf("\n");
        for(i=len();i>=0;i--)
            printf("%c",a[i]);
        printf("\n-------------------\n");
    }

    void add()
    {
        int k,v=0;
        for(k=0;k<len();k++)
        {
            v=2*(((int)a[k])-48);
            a[k]=v+48;
        }
        for(k=0;k<len();k++)
        {
            if((int)a[k]>57)
            {
                if(k<(len()-1))
                {
                    a[k+1]+=1;
                    a[k]=((((int)a[k])-48)%10)+48;
                }//in if 1
                if(k==len()-1)
                {
                    realloc(a,(len()+1)*sizeof(char));
                    a[k+1]=49;
                    a[k]=((((int)a[k])-48)%10)+48;
                }//in if 2
            }//out if
        }//for
    }//add

    int main()
    {
        int j;
        a=(char *)calloc(1,sizeof(char));
        a[0]='1';
        for(j=1;j<=81;j++)
        {
            add();
            printf(" %d :\n",j);
            rev();
        }
        scanf("%d",&i);
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

我不明白出了什么问题......确实realloc有一个限制是分配内存还是我的系统故障?


编辑:

正如@DavidSchwartz建议我必须将新返回的指针起始地址分配给变量

a=realloc(a,(len()+1)*sizeof(char));
Run Code Online (Sandbox Code Playgroud)

我想如何有效地检测和避免过流.

Dav*_*rtz 5

您忽略了返回值,realloc并继续使用可能存在或可能不存在的旧存储块.当然你的意思是:

        a = realloc(a,(len()+1)*sizeof(char));
Run Code Online (Sandbox Code Playgroud)

  • @ ch3rub7传递`a`的值来告诉`realloc`需要重新分配哪个内存块.但是你需要捕获(可能)新块的地址,因为它可能不同. (2认同)

aut*_*tic 5

您需要分配'\0'给您的数组(在您分配的范围内).

考虑一个存储在鸡蛋盒中的假想数组的鸡蛋.如果你告诉某人在纸箱开始处有一系列的鸡蛋一直持续到它们到达一个终端蛋(看起来与其他鸡蛋不同的东西),当他们找不到终端蛋时会发生什么?心灵爆炸就是这样.他们可能会对你大吼大叫并指责你表现得很愚蠢; 行为未定义.

从计算机的角度来看,我们应该继续寻找终端蛋,经过纸箱的另一端,到地板上,出门,上路和啪啪 ......我们被车撞了; 行为未定义,但又一次.

你需要将终止蛋放入纸箱中.请记住,这意味着您还需要为终止鸡蛋腾出空间.


将返回值存储realloc到临时变量中!

事实上,realloc 确实存在局限性,C的其他部分也是如此:正如您所观察到的那样,限制主要影响那些猜测如何使用它而不是阅读(手册)的人.该手册有两点要点:

  • 可能realloc会分配一个具有不同地址的对象,它通过返回值进行通信.
  • realloc出现故障时,它会返回NULL.重要的是不要在溢出数组时充电,并注意指针不是freed; 如果用新的(null)指针值覆盖旧的指针值,你将无法使用 free它...你将泄露内存.

实际上,您应该(几乎)始终检查每个标准C函数的返回值.如果您不知道如何操作,请找到相应的手册并阅读.如果您无法阅读本手册而不会对从上到下的所有内容感到困惑,那么您需要一本更好的书,因为您还没有掌握基础知识.

这是你应该(几乎)总是使用的方式realloc:

void *temp = realloc(array, size);
if (temp == NULL) {
    /* XXX: Handle allocation failure */
}
array = temp;
Run Code Online (Sandbox Code Playgroud)

如何从分配失败中恢复是您的决定,但重要的是您可以从分配失败中恢复(并且不会同时泄漏内存).XXX在上面的代码中填写空格(注释)的简单解决方案是:

void *temp = realloc(array, size);
if (temp == NULL) {
    free(array); // This'll stop valgrind from complaining about leaked memory
    exit(EXIT_FAILURE);
}
array = temp;
Run Code Online (Sandbox Code Playgroud)

你有没有特别的理由不使用strlen?也许你的书还没有教过你.


((((int)a[k])-48)%10)+48;
Run Code Online (Sandbox Code Playgroud)

这是什么?你的书没有告诉你,你可以加减法中的常量吗?这样更便携,更易读:(a[k] - '0') % 10 + '0'

关于书籍的主题,显然你的书不适合你.我相信你会受益于K&R"The C Programming Language,2nd edition".当你遇到它们时做练习; 不要跳过它们.


还有一件事:不要施放malloc,realloc或者calloc

  • 很好的答案.也没有任何理由乘以`sizeof(char)`,因为它总是定义为`1`. (2认同)