【问题标题】:Add zeros to String in C在C中向字符串添加零
【发布时间】:2017-05-30 07:26:19
【问题描述】:

我想用这个方法在字符串前面加零:

void addFrontzeros(char *str,int zeros)
{
    if(zeros==0)
    {
        return;
    }

    char *temp=malloc((strlen(str)+1+zeros)*sizeof(char));

    int i=0;
    for(;i<zeros;i++)
    {
        temp[i]='0';
    }

    int j=0;
    for(;j<strlen(str);j++)
    {
        temp[j+zeros]=str[j];
    }
    temp[strlen(str)+zeros]=0;
    str=realloc(str,(strlen(temp)+1)*sizeof(char));
    strcpy(str,temp);
    free(temp);
}

但是当我从另一个方法调用它时,调用后字符串为空。 调用者字符串在另一种方法中是这样分配的:

char *mul = malloc(sizeof(char)*2);
    mul[0]='0';
    mul[1]=0;

使用 valgrind 我得到了这个错误: 地址 0x5201b00 是大小为 2 的块内的 0 个字节已释放

我认为问题出在 realloc 上,但我不知道为什么它在这里不起作用

【问题讨论】:

  • 您在离开函数后丢失了realloc 返回的指针(因为它被分配给本地指针),而且您没有在第二个循环中设置空终止符

标签: c string pointers realloc


【解决方案1】:

通过调用realloc,您(可能)在函数内部修改str,但addFrontzeros 的调用者看不到str 的新值。它仍然有旧版本的str,在realloc 之后不再指向有效数据。

你的函数应该要么return str(这样它可以被称为x = addFrontzeros(x, n))要么接受一个char **,这样它就可以修改指针。

正如 StoryTeller 所指出的,str = realloc(str, ...)realloc 失败的情况下是不安全的。首先,因为您没有测试realloc 是否返回NULL,其次,因为如果它确实 返回NULL,则您有内存泄漏,因为旧的str 仍然被分配但你失去了指向它的指针。处理它的最小方法是

char *new_str = realloc(str, strlen(temp)+1);
if (!new_str) {
    perror("addFrontzeros: realloc");
} else {
    str = new_str;
}

虽然如果您想以其他方式处理故障,您可以,并且原来的str 仍然有效且未经修改。

另一个问题是您只复制strlen(str) 字节,其中不包括终止零字节,因此您的字符串未正确终止。要么自己添加终止零,要么简单地再复制一个字节(因为您可以假设 str 正确终止以开始)。

最后,作为旁注,sizeof(char) 根据定义为 1,因此不需要乘以它。

【讨论】:

  • 盲目地将realloc的结果赋值给已有的指针也是不安全的。
  • @StoryTeller 这是因为失败时它会返回NULL 但不会修改现有内存,所以盲目重新分配会导致泄漏,对吗?
  • 是的,这就是我的想法。重新分配失败可能并不一定意味着您的程序是烤面包(比如zeros 是否很大)。函数失败不应修改str
  • @StoryTeller 好的,我在这个方向上添加了一些建议。尽量不要太啰嗦。 :)
  • 谢谢,我现在更改它以返回指针,现在它可以工作了
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多