realloc()

时间:2016-03-28 17:41:41

标签: c

在这里,我尝试编写代码,通过操作字符串来查找2的幂。我知道这可以通过一些内置函数来完成,但我对使用字符串操作技术这样做感兴趣。

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

这是我的代码。希望我能找到你的帮助会出现什么问题。

CODE

  

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

     
      
  1. int len():找到字符串的长度。
  2.   
  3. void add():执行操作以找到2的力量。
  4.   
  5. void rev():以相反的顺序显示字符串,作为所需的输出。
  6.   
  7. int main()
  8.   
    #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;
    }

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

修改

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

a=realloc(a,(len()+1)*sizeof(char));

我希望如何有效地检测并避免过流。

3 个答案:

答案 0 :(得分:5)

您忽略了 a = realloc(a,(len()+1)*sizeof(char)); 的返回值,并继续使用可能存在或可能不存在的旧存储块。当然你的意思是:

for(int index = 0 ; index < s.length ; index++){
    //Logic
}

答案 1 :(得分:5)

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

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

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

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

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

事实上,realloc 确实有限制,C的其他部分也有限制:这些限制主要影响那些猜测如何使用它的人正如你所观察到的那样,而不是阅读(the manual)。该手册有两点需要注意:

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

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

以下是您应该(几乎)始终使用realloc的方式:

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

如何从分配失败中恢复是您的决定,但重要的是您可以从分配失败中恢复(并且不会同时泄漏内存)。在上面的代码中填写空格(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;

您是否有任何特殊原因未使用strlen?也许你的书还没有教过你。

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

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

还有一件事:Don't cast malloc, realloc or calloc

答案 2 :(得分:1)

realloc不会修改传递给它的指针。相反,它返回一个新指针,如果内存中有足够的可用空间,那么可能就是你传递给它的指针。

而不是realloc(a,(len()+1)*sizeof(char));,您应该使用a = realloc(a,(len()+1)*sizeof(char));

您可以在此处了解有关realloc的更多信息:http://www.cplusplus.com/reference/cstdlib/realloc/