正如有些人所说,这个区块并没有像我想象的那样。我试图分配内存块,然后将字符串文字存储在其中 - 但现在再次查看它后,很明显这不是我在这里所做的。
如果您这样做有什么区别:
char* memory = malloc(sizeof("String"));
memory = "String"; //edit: memory leaked
printf("%s", memory);
free(memory); //edit
或者这个:
char* noMemory = "String";
printf("%s", noMemory);
答案 0 :(得分:2)
在您的特定示例中,您正在泄漏内存并最终导致未定义的行为以尝试释放常量字符串"string"
,因为您首先分配memory
,然后为其分配地址{ {1}},因此失去对原始分配的跟踪。
您需要使用"string"
复制字符串。
现在,除此之外,除非你这样做,否则你会浪费很多时钟周期,因为strcpy(memory, "String");
和malloc
不是免费操作,它们需要时间,而且当然,复制字符串也需要一些操作。最重要的是,分配有free
的内存将占用比实际字符串更多的空间,因为malloc
和malloc
函数需要在“内存旁边”提供一些信息阻止能够完成他们的工作,并且因为通常,大小被四舍五入到一些“好”的大小,例如8,16或32个字节。这意味着您不仅浪费时钟周期调用malloc和free,而且还使用了比实际要求更多的内存。因此,您可能使用40或64字节而不是使用7个字节。
另一方面,如果你想修改字符串,那么你不能只使用free
的现有内存,因为这不能保证是“可写”内存,所以再次,你结束使用"String"
(这可能意味着任何现代操作系统崩溃)。然而,还有其他几种可能的解决方案,例如:
undefined behaviour
将为堆栈上的字符串提供15个字节的空间 - 对于[最多7个字节]的空间量没有开销,我们可以忽略分配它的开销。堆栈,因为它是一个单一的指令,如果你完全使用局部变量就必须存在 - 并且它是所有局部变量的一条指令。
此解决方案允许修改字符串(例如 char local[15] = "String";
以生成strcat(local, " abc");
。只需确保您知道自己在做什么,并且不要覆盖允许空间的末尾[并且不要不要忘记字符串末尾的零点。
答案 1 :(得分:2)
这两个版本之间的差异如下:
另一方面,第二个版本(差不多)好了。你应该得到一个警告,因为指针应该是'const'。
如果要将字符串分配给分配的内存,则应使用strcpy
或者使用strdup
,在这种情况下,您不需要malloc
您仍然需要释放它。另一种方法是静态地为字符串分配一个数组,因为你已经知道了字符串。
修改强>
关于您在其他帖子中的评论:
如果您有文字字符串,它将存储在BSS段中。所以你可以直接使用它,而不需要为它分配额外的空间。但是,有一个限制,你不应该修改这样的字符串,因为这是未定义的行为。操作系统可能会选择将此类数据保存在受保护的内存中,这可能会导致程序出现段错误,或者可能会有效。