没有 malloc 或 calloc 的 free() 函数
快速问题
您可以使用 free() 函数而无需事先调用 malloc 吗?
呃。
void someFunc( void )
{
char str[6] = {"Hello"};
//some processing here ....
free(str);
}
我没有遇到编译错误,但是这有效还是完全正确?
谢谢你,
quick question
Can you use the free() function without having to prior call a malloc ??
ei.
void someFunc( void )
{
char str[6] = {"Hello"};
//some processing here ....
free(str);
}
I get no compiling errors but Does this work or is it correct at all ?
Thank you,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是完全不正确的:
char str[6]
。This is not at all correct:
char str[6]
.当您调用 malloc() 或任何其他分配函数时,内存将在堆上分配。这是唯一可以释放的内存。当您声明静态字符串时,正如您在示例中所做的那样,该字符串会在编译时分配到另一个内存段中。
str
指针本身也是如此,它分配在 堆栈,因此也无法释放。When you call malloc() or any other allocation function, memory will be allocated on the heap. This is the only memory that can be freed. When you declare a static string, as you've done in your example, the string is allocated at compile time in another memory segment. The same goes for the
str
pointer itself which is allocated on the stack, and thus cannot be freed either.在非 malloc 变量上使用 free 通常会导致段错误。示例:
$ gcc test.c -o test
$ ./test
分段错误
Using free on a non-malloc'd variable will result in a Segfault generally. Example:
$ gcc test.c -o test
$ ./test
Segmentation fault
free() 使用分配块前面的数据来管理堆。如果指向的内存不是由堆分配函数(例如 malloc() 或 calloc())分配的,则该块前面的数据作为堆管理数据将毫无意义。
有些库会检测无效的堆数据并产生运行时错误,否则行为未定义。通常,此类错误的后果将不会被注意到,直到您稍后尝试分配更多内存为止。这会使调试此类错误变得非常困难。
您不会收到编译器错误,因为它不是语法错误并且在编译时无法检测到。编译器不了解库函数的语义。它只知道 malloc() 返回 void* 并且 free() 接受 void*;在编译时无法知道指针是否引用动态分配的块,因为内存根据定义是在运行时分配的。此外,指针可以在运行时修改为指向任何内存类型,或者可以使用别名 - 复制到另一个指针,然后通过第二个指针释放。如果您期望出现错误消息,那么您对编译器的期望很高;然而,一些静态分析工具可能会警告是否可能发生此类错误,而动态分析工具(例如 valgrind)可能会在测试过程中实际发生错误时检测到该错误。
free() uses data prepended to the allocated block to manage the heap. If the memory pointed to was not allocated by a heap allocation function such as malloc() or calloc(), then the data preceeding the block will be meaningless as heap management data.
Some libraries will detect invalid heap data and yieled a runtime error, otherwise the behaviour is undefined. Often the consequences of such an error will remain unnoticed until you later attempt to allocate further memory. This can make debugging such errors very difficult.
You would not get a compiler error because it is not a syntactic error and is not detectable at compile time. The compiler has no knowledge of the semantics of library functions. All it knows is that malloc() returns a void* and that free() accepts a void*; there is no way of knowing at compile time whether the pointer refers to a dynamically allocated block because the memory is by definition allocated at runtime. Also a pointer may be modified at runtime to point to any memory type, or may be aliased - copied to another pointer and then free'd through the second pointer. You expect a lot of the compiler if you expect an error message; however some static analysis tools may be able to warn if such an error may occur, and dynamic analysis tools such as valgrind may detect the error when and if it actually occurs during testing.
否
free(3)
函数采用void *
参数,因此您可以向其传递任何类型的指针,而不会出现编译时错误。但是,如果指针最初不是由malloc(3)
返回并且之前从未返回给free(3)
,就会发生不好的事情。No
The
free(3)
function takes avoid *
parameter, so you can pass it any sort of pointer without a compile-time error. But bad things will happen if the pointer wasn't originally returned bymalloc(3)
and never previously given back tofree(3)
.你不能,但你不需要。当您在函数内声明一个变量时,它被称为自动变量,因为它在函数结束时自动被删除(释放其内存)。
如果您想限制自动变量的生命周期,您可以使用
{}
引入作用域,如下所示:为了清晰起见,无需额外注释:
在函数内引入新作用域是一个常见的习惯用法,用于清理更广泛范围的无关变量(潜在的错误来源),同时也可以利用RAII。
例如,当锁定互斥锁以同步函数代码的一小部分时。
You can't, but you don't need to. When you declare a variable inside a function as you have it is called an automatic variable because it gets deleted (freeing its memory) automatically at the end of the function.
If you want to restrict the lifetime of an automatic variable you can introduce a scope using
{}
like this:Without the extra comments for clarity:
Introducing a new scope inside a function is a common idiom used to clean up the broader scope of extraneous variables (a potential source of bugs) but also to leverage the power of RAII.
For example when locking a mutex to synchronize a small portion of the function's code.