【问题标题】:Duplicating a string in C (Include memory allocating, pointers, etc.)在 C 中复制字符串(包括内存分配、指针等)
【发布时间】:2017-01-18 20:31:59
【问题描述】:

这是我目前的代码:

char * duplicate(char *str)
{
    int len = strlen(str) + 1;
    char *ptr;
    ptr = (char *)malloc(len);
    strcpy(ptr, str);
    str = (char *)realloc((void *)str, len * 2 * sizeof(char));
    strcat(str, ptr);
    free((void *)ptr);
    present(str);
    return(str);
}

旁注:我知道我应该检查内存是否实际分配,我稍后会这样做。

程序要求用户输入一个字符串,然后将其加倍并打印出新字符串。 present->a 我创建的函数可以将字符串打印出来。

现在我的思路是这样的:

1) 为占位符指针分配内存,将str字符串复制到ptr

2) 为str 重新分配内存,现在大小增加了一倍

3) 使用strcat复制字符串

4) 释放ptr 内存

输出应该如下:

string input by users for example: "Hi"

output: "HiHi"

如果我们再次运行该函数,输出应该是:"HiHiHiHi"

我面临的问题是,在运行该函数大约 2-4 次后(取决于输入字符串的大小),程序会崩溃,它会说它有一个触发点,类似于:"wntdll.pdb not loaded".

我相信这与内存有关,因为如果我尝试复制较大的字符串,它会在第一次之后崩溃。

我是否正确分配内存?我现在不知道该怎么办。

感谢您的帮助:)

【问题讨论】:

标签: c string memory duplicates


【解决方案1】:

您不需要额外的分配:

char * duplicate(char *str)
{
    size_t len = strlen(str);
    char *ret = realloc(str, 2*len+1); //assuming no overflow
    if(ret){
        memcpy(ret+len, ret, len);
        ret[2*len]=0;
    }
    return ret;
}

【讨论】:

  • 谢谢,这是非常有用的!我的问题是,memcpy 是做什么的? (显然它会复制内存块)但是如果不使用这个函数我怎么能重新创建呢?提前致谢。
  • 使用你的代码后,同样的事情发生了,我可以复制一个字符串几次,在第 3-5 次程序崩溃之后。
  • @Dimakossover 向我们展示整个代码。也许你做了一些非法的事情,比如duplicate("foo");char *foo = "foo"; duplicate(foo);。 (你明白为什么这是非法的吧?)
  • 嗨@DavidSchwartz我在这里复制了相关代码:pastebin.com/VssF3wBe,提前致谢。
  • @Dimakossover 由于您有太多与ptr_s 混淆的代码,因此错误可能在任何地方。我会先看看get。 (或者给我们足够的代码来重现问题。)
【解决方案2】:

你可以通过使用strdup来避免所有的样板:

char *s1 = "String";
char *s2 = strdup(s1);
...
free(s2);

你的函数会变成:

char* duplicate(char const *str) {
  char *ptr = strdup(str);
  ptr = (char*) realloc(ptr, 2 * strlen(str) + 1);
  strcat(ptr, str);

  return ptr;
}

Live Demo

【讨论】:

  • 谢谢,它确实清除了一些东西!对我的其他问题有任何想法吗?因为字符串会重复,但如果它太长就会崩溃。
  • @Dimakossover 多长时间?
  • 如果输入的字符串是:"hi",会复制两次,所以变成hi->hihi->hihihihi->hihihihihihihihi->此时会crash。 (再次调用重复函数后。)
  • 做出有根据的猜测,我认为在您的版本中返回输入字符串是不理智的。你看,你实际上是在改变输入缓冲区。
  • 你好@101010 实际上我忘了把新值从代码中传递给 main 中的 ptr_s,现在我已经完成了,一切都很好,没有崩溃,非常顺利,谢谢你的关注和帮助,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
相关资源
最近更新 更多