【问题标题】:Difference between malloc and realloc?malloc 和 realloc 的区别?
【发布时间】:2012-11-12 19:49:23
【问题描述】:

假设我有两个代码示例用于创建一个包含 10 个元素的整数数组:

int *pi = (int*)0; 
realloc(pi,10);

另一个是正常写的,即:

int *pi;
pi= malloc(10*sizeof(int));

现在,我的问题是:第一种类型的赋值是合法的,但没有使用。为什么,虽然我可能会得到我选择的起始位置?
用常量初始化指针是合法的,但不被使用。为什么?

【问题讨论】:

  • 你不应该在 C 中强制转换 malloc 的返回值。

标签: c pointers


【解决方案1】:

NULL 被传递时,realloc 等价于malloc。如果您在某种循环中重新分配并且不想在第一次分配时出现特殊情况,则NULL 调用可能很有用。


虽然我们正在使用它,但使用 malloc 和 realloc 的相当标准的方法是:

int* p;
p = malloc(10 * sizeof(int)); //Note that there's no cast
//(also, it could just be int* p = malloc(...);)

int* np = realloc(p, 15 * sizeof(int));
//Note that you keep the old pointer -- this is in case the realloc fails

顺便说一句:历史是您在不同行上看到声明和赋值的主要原因。在旧版本的 C 中,声明必须放在函数的首位。这意味着即使你的函数直到 20 行才使用变量,你也必须在顶部声明。

由于您通常不知道未用于另外 20 行的变量的值应该是什么,因此您不能始终将其初始化为任何有意义的值,因此您只剩下一个声明并且在功能的顶部。

在 C99/C11 中,您不必在作用域的顶部声明变量。事实上,一般建议定义变量尽可能接近其用途。

【讨论】:

  • NULL。只要编译器不抛出编译错误,这是合法的。
  • 但是在虚拟内存环境中我的程序拥有整个内存
  • @me.deeiip 不,这是一个错误的假设。您不能只使用任意内存地址,您使用的地址必须由其他功能授予您,以确保系统知道如何允许您使用它们。
  • @me.deeiip 那是因为你已经进入了未定义行为的世界。未定义行为中可能存在的一种行为是“正确”行为,但不能保证。
  • @me.deeiip:行为是未定义;它可能看起来正常工作,但这是偶然的,而不是设计。 realloc 的第一个参数必须为 NULL 或 *alloc 函数之一的结果。
【解决方案2】:

C 要求传递给realloc 的指针必须是从malloccallocrealloc 函数调用获得的指针(或空指针)。

【讨论】:

  • calloc 或之前的realloc,或许还有其他人?
  • @mah 谢谢,已添加到我的答案中。
  • @mah 来自alloc 系列函数可能是最好的表达方式。
  • @dmckee 一个过于谨慎的评论者可能已经添加了“从尚未释放的 alloc 系列函数中获得的[a pointer]”,但这将是多余的:释放任何版本的指针使其所有副本都不确定。从某种意义上说,其他副本不再存在,因此无法传递给realloc()free()blog.frama-c.com/index.php?post/2012/01/05/Double-free
  • ::摇摇晃晃地紧紧抓住心脏:: 哦,我有祸了!出挂件!再次! ::摔倒在地,唱咏叹调,死得很长:: @PascalCuoq 你赢了。
【解决方案3】:

第一个赋值是合法的,因为你传递给realloc() 的指针一定是之前通过某种分配给你的。 (此外,你忽略了它的返回值,这是你绝对不能对分配做的事情!)

malloc() 是为一些固定大小的东西创建一个缓冲区。 realloc() 是返回一个缓冲区并获得另一个(可能)不同大小的缓冲区——它可能会返回你正在使用的相同缓冲区。

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2018-07-06
    • 2018-08-29
    • 2021-01-15
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多