【问题标题】:Do you need to free a string from 'strcpy' if you copy a string generated from malloc?如果复制从 malloc 生成的字符串,是否需要从“strcpy”中释放字符串?
【发布时间】:2022-01-04 09:42:27
【问题描述】:

假设我有一些代码 sn-p

char *str = malloc(sizeof(char)*10)
// some code to add content to the string in some way

创建一个 10 个字符的字符串。如果我然后将strstrcpy 从标准字符串库复制到一个新变量中,就像这样

char *copy;
strcpy(copy, str);

我知道我需要使用free(str) 释放str,但这是否足够?或者strcpy 是否也为copy 动态分配内存,如果用于从 malloc 创建的字符串?

【问题讨论】:

    标签: c string dynamic-memory-allocation free


    【解决方案1】:

    或者 strcpy 是否也为复制动态分配内存

    不,strcpy 对内存一无所知,因此您的代码将字符串复制到指向 la-la 土地的未初始化指针中。

    如果您想在同一个调用中分配 + 复制,则有非标准的 strdup (看起来它将在下一版本的语言中添加到 C 标准中)。

    或者只做char *copy = malloc(strlen(str)+1); 然后strcpy。请记住始终为空终止符留出空间。

    【讨论】:

    • Afaik strcpy 也复制空终止符。这是否意味着如果我 100% 确定我复制的字符串有一个空终止符,我就不需要你的 malloc 调用中的 +1?
    • @SomeCoderOnTheWeb strcpy 复制终结器,但您必须确保有空间。如果字符串长度为 10 个字符,那么显然需要分配 11 个,否则 strcpy 在写入终止符时会越界访问数据。
    • @SomeCoderOnTheWeb 不,因为strlen 不计算空终止符。 strlen("abc" ) == 3,而底层 char 数组的大小为 4,{'a','b','c', '\0'} 并且需要复制的内容(并由 strcpy 复制)。
    【解决方案2】:

    strcpy 不分配,因此您的第二个 sn-p 无效,除非 copy 使用某个缓冲区(无论它是分配堆栈还是堆分配)进行初始化,或者是一个足够大的数组。

    旁注:如果您不知道源字符串的确切长度,则需要确保不超过目标缓冲区大小(例如使用strncpy 或提供足够大的目标缓冲区)。

    我猜documentation应该会详细回答你的问题。

    【讨论】:

    • strncpy 是一个糟糕的选择,因为它可能会让您没有空终止符。
    • @Jabberwocky 可能,但在已知大小的情况下,恕我直言,这并不是什么大问题。当然,我可能还会选择其他方法,但这确实取决于上下文。
    • @Jabberwocky 那你会推荐什么?
    • @SomeCoderOnTheWeb 使用strcpy 并确保目标缓冲区足够长。
    • 告诉人们使用strncpy 总是不好和不正确的建议。请学习Is strcpy dangerous and what should be used instead?
    【解决方案3】:

    对于初学者来说,指针副本未初始化

    char *copy;
    

    所以这个 strcoy 的调用

    strcpy(copy, str);
    

    导致未定义的行为。

    指针copy必须指向一个字符数组,指针str指向的字符串将被复制到该数组中。

    您需要释放使用 malloc、calloc 或 realloc 分配的内容。

    因此,如果指针副本指向的目标数组是动态分配的,例如

    char *copy = malloc( 10 * sizeof( char ) );
    

    当然,当不再需要分配的内存时,您将需要释放它。

    这与函数strcpy 没有任何共同之处,它只是将字符串从一个字符数组复制到另一个字符数组。

    【讨论】:

      猜你喜欢
      • 2011-06-30
      • 1970-01-01
      • 2016-02-28
      • 2014-01-21
      • 2014-12-13
      • 2015-08-06
      • 2011-03-03
      • 2016-02-22
      • 2021-02-18
      相关资源
      最近更新 更多