-1

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

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

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

或这个:

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

2 回答 2

2

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

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

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

另一方面,如果您想修改字符串,那么您不能只将现有内存"String"用于undefined behaviour在任何现代操作系统上崩溃)。但是,还有其他几种可能的解决方案,例如:

 char local[15] = "String";

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

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

于 2013-08-18T21:02:07.490 回答
2

这两个版本的区别如下。

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

另一方面,第二个版本(几乎)没问题。你应该得到一个警告,因为指针应该是'const'。

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

编辑

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

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

于 2013-08-18T21:02:41.390 回答