c-在这段代码中使用malloc和不使用它有什么区别



正如一些人所说,这个块并没有像我想象的那样。我试图分配内存块,然后将字符串文本存储在其中,但现在再看一遍,很明显这不是我在这里所做的

如果你这样做有什么区别:

    char* memory = malloc(sizeof("String"));
    memory = "String"; //edit: memory leaked
    printf("%s", memory);
    free(memory); //edit

或者这个:

    char* noMemory = "String";
    printf("%s", noMemory);

在您的特定示例中,由于您首先分配memory,然后为其分配"string"地址,因此丢失了对原始分配的跟踪,因此您正在泄漏内存,并在尝试释放常量字符串"string"时出现未定义的行为。

您需要使用strcpy(memory, "String");来复制字符串。

除此之外,除非你只是这样做,否则你会浪费很多时钟周期,因为mallocfree不是空闲操作,它们需要时间,当然,复制字符串也需要一些操作。除此之外,分配有malloc的内存将比实际字符串占用更多的空间,这既是因为mallocfree函数需要内存块"旁边"的一点信息才能完成它们的工作,也是因为通常情况下,大小会四舍五入到一些"好"的大小,例如8、16或32字节。这意味着调用malloc和free不仅浪费了时钟周期,而且使用的内存也比实际要求的要多。因此,您可能使用的不是7个字节,而是40或64个字节。

另一方面,如果你想修改字符串,那么你不能只使用"String"的现有内存,因为这不能保证是"可写"内存,所以你最终会得到undefined behaviour(这可能意味着任何现代操作系统都会崩溃)。然而,还有其他几种可能的解决方案,例如:

 char local[15] = "String";

将为堆栈上的一个字符串提供相当于15个字节的空间-在空间量上没有开销[最多7个字节],我们可以忽略在堆栈上分配它的开销,因为如果你使用局部变量,它是一条必须存在的指令-它是所有局部变量的一条指令。

这个解决方案允许修改字符串(例如strcat(local, " abc");使其成为"string abc"。只需确保您知道自己在做什么,并且不要覆盖允许空间的末尾[并且不要忘记计算字符串末尾的零]。

这两个版本之间的区别如下。

  1. 在第一个版本中,您分配的内存正在泄漏,因为您没有使用返回的内存,而是立即用新值(指向静态分配的字符串的指针)覆盖它
  2. 此外,您可以将内存释放给静态分配的字符串,因为您已经丢失了分配的指针。这将导致未定义的行为

另一方面,第二个版本(几乎)可以。不过你应该得到一个警告,因为指针应该是"const"。

如果您想将字符串分配给分配的内存,您应该使用strcpy,或者您可以使用strdup,在这种情况下,您不需要malloc,但您仍然必须释放它。另一种方法是为字符串静态分配一个数组,因为您已经知道该字符串了。

编辑

关于你在其他帖子中的评论:

如果您有一个文字字符串,它将存储在BSS段中。所以你可以直接使用它,而不需要为它分配额外的空间。然而,有一个限制,你不应该修改这样的字符串,因为这是未定义的行为。操作系统可能会选择将这些数据保存在受保护的内存中,这可能会导致程序发生故障,或者它可能会工作。

相关内容

  • 没有找到相关文章

最新更新