在此代码中使用malloc或不使用它有什么区别?

时间:2013-08-18 20:37:39

标签: c memory malloc

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

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

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

或者这个:

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

2 个答案:

答案 0 :(得分:2)

在您的特定示例中,您正在泄漏内存并最终导致未定义的行为以尝试释放常量字符串"string",因为您首先分配memory,然后为其分配地址{ {1}},因此失去对原始分配的跟踪。

您需要使用"string"复制字符串。

现在,除此之外,除非你这样做,否则你会浪费很多时钟周期,因为strcpy(memory, "String");malloc不是免费操作,它们需要时间,而且当然,复制字符串也需要一些操作。最重要的是,分配有free的内存将占用比实际字符串更多的空间,因为mallocmalloc函数需要在“内存旁边”提供一些信息阻止能够完成他们的工作,并且因为通常,大小被四舍五入到一些“好”的大小,例如8,16或32个字节。这意味着您不仅浪费时钟周期调用malloc和free,而且还使用了比实际要求更多的内存。因此,您可能使用40或64字节而不是使用7个字节。

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

undefined behaviour

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

此解决方案允许修改字符串(例如 char local[15] = "String"; 以生成strcat(local, " abc");。只需确保您知道自己在做什么,并且不要覆盖允许空间的末尾[并且不要不要忘记字符串末尾的零点。

答案 1 :(得分:2)

这两个版本之间的差异如下:

  1. 在第一个版本中,您分配了泄漏的内存,因为您不是使用返回的内存,而是立即用新值(指向静态分配的字符串的指针)覆盖它。
  2. 此外,您将内存释放到静态分配的字符串,因为您已经丢失了分配的指针。这将导致未定义的行为。
  3. 另一方面,第二个版本(差不多)好了。你应该得到一个警告,因为指针应该是'const'。

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

    修改

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

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