c/c++开发分享C:自动变量免费通话?

int main() { int x = 0; free(x); } 

这编译并且似乎是无操作。 究竟发生了什么? 是这个行为定义的?

谢谢!

    不,行为未定义。 而且,代码不应该编译。

    首先,代码不应该编译,因为它包含约束违规。 作为free的操作数传递的表达式具有int类型。 free的参数有void *类型。 int值可以隐式转换为void * type的唯一情况是int值是值为0的积分常量表达式(ICE)。 在你的情况下, x不是ICE,这意味着它不能隐式转换为void * 。 您的代码编译的唯一原因是,由于历史原因(支持遗留代码),您的编译器会悄悄地忽略free(x)调用中出现的约束违规。 我敢肯定,如果你提高编译器中的警告级别,它会抱怨(至少有警告)。 一个迂腐的编译器会立即发出一个错误的free(x)调用。 尝试使用Comeau Online,例如在C89 / 90模式下:

     "ComeauTest.c", line 6: error: argument of type "int" is incompatible with parameter of type "void *" free(x); ^ 

    (另外,你还记得在free电话之前加入stdlib.h吗?)

    其次,让我们假设代码编译,即编译器将其解释为free((void *) x) 。 在这种情况下,非常数整数值x被转换为指针类型void * 。 此转换的结果是实现定义。 注意,该语言保证当值为0的ICE转换为指针类型时,结果为空指针。 但在你的情况下, x不是ICE,因此转换的结果是实现定义的。 在C中,无法保证通过将值为0的非ICE整数转换为指针类型来获取空指针。 在你的实现上,可能恰好发生了(void *) x其中非ICE x等于0产生类型为void *的空指针值。 传递给free ,此空指针值会根据free的规范产生no-op。

    但是在一般情况下,将这样的指针传递给free将导致未定义的行为。 你可以合法地传递给free的指针是先前调用malloc / calloc / realloc和null指针获得的指针。 在一般情况下,您的指针违反此约束,因此行为未定义。

    这就是你的情况。 但是,您的代码再次包含约束违规。 即使您覆盖违规,行为也是未定义的。

    PS注意,顺便说一句,这里已经发布的许多答案都犯了同样严重的错误。 他们假设(void *) x和零x应该产生一个空指针。 这绝对不正确。 同样,当x不是ICE时,语言绝对不能保证(void *) x的结果。 (void *) 0保证为空指针,但(void *) x与零x 保证是空指针。

    这将在C FAQ 。 对于那些有兴趣更好地理解其原因的人来说,阅读有关空指针的整个部分可能是个好主意http://c-faq.com/null/index.html

    在你的情况下,它的工作原理是因为调用free(NULL)(即free(0))是一个NOOP。 但是,如果使用0以外的任何值(NULL)调用它,则行为将是未定义的 – 崩溃和/或内存损坏可能是候选者。

    编辑:正如其他人后来指出的那样,free(x)(x = 0)和free(NULL)不是一回事。 (虽然它通常为0,但NULL指针的值是实现定义的,不能依赖它。)请参阅AndreyT的答案以获得非常好的说明。

    释放NULL(或0)什么都不做。 这是一个无操作。

    您是否尝试过编译器的警告级别? 例如gcc -ansi -pedantic -W -Wall报告:

    tmp.c:6:警告:传递’free’的参数1使得整数指针没有强制转换

    行为未定义。 不要这样做。

    free手册页:

    free()释放ptr指向的内存空间,该内存空间必须由之前调用malloc(),calloc()或realloc()返回。 否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为。 如果ptr为NULL,则不执行任何操作。

    在你的例子中,你实际上是在调用free(0) ,因为free接受一个指针作为参数。 你实际上是在告诉运行时释放地址0的内存,而这个内存以前没有malloc分配过。

    由于’0’为NULL,所以不会发生任何事情。 (感谢评论指出我的愚蠢错误)。

    free()适用于动态分配的内存,即使用malloc,calloc或realloc分配的内存。 此外,它需要一个指针,你传递的是x的值。 没有理由在堆栈分配的变量上调用它,当堆栈展开并且行为未定义时将释放它们。 总是很好阅读文档。

    它应该在大多数体系结构上抛出访问冲突。 好吧,它是0,所以它的工作原理,但如果它不是0,它将失败。 这是未定义的。 你不能free()一个堆栈分配变量。

         free(0);   “使用NULL值调用自由函数,将无效。”  

    实际上,当我们释放使用内存时,它会产生影响。

    这里x值为零,因此它不会产生任何问题。 如果x的值不是

    在这种情况下,它可能会出现分段错误。 因为x值可能用作

    记忆表示一些其他变量。

      以上就是c/c++开发分享C:自动变量免费通话?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(猴子技术宅)。

      本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/546027.html

      发表评论

      电子邮件地址不会被公开。 必填项已用*标注