没有 malloc 或 calloc 的 free() 函数

发布于 2024-09-30 12:46:47 字数 234 浏览 5 评论 0原文

快速问题

您可以使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

魔法唧唧 2024-10-07 12:46:47

这是完全不正确的:

  1. 您无法释放静态数组,例如 char str[6]
  2. free() 只能在您分配的内存上(或 NULL)调用。

This is not at all correct:

  1. You cannot free a static array such as char str[6].
  2. free() should only be called on memory you allocated (or on NULL).
儭儭莪哋寶赑 2024-10-07 12:46:47

当您调用 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.

平定天下 2024-10-07 12:46:47

在非 malloc 变量上使用 free 通常会导致段错误。示例:

#include <stdlib.h>

int main()
{
  char str[6] = {"Hello"};
  free(str);
}

$ gcc test.c -o test

$ ./test

分段错误

Using free on a non-malloc'd variable will result in a Segfault generally. Example:

#include <stdlib.h>

int main()
{
  char str[6] = {"Hello"};
  free(str);
}

$ gcc test.c -o test

$ ./test

Segmentation fault

眼角的笑意。 2024-10-07 12:46:47

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.

电影里的梦 2024-10-07 12:46:47


free(3) 函数采用 void * 参数,因此您可以向其传递任何类型的指针,而不会出现编译时错误。但是,如果指针最初不是由 malloc(3) 返回并且之前从未返回给 free(3),就会发生不好的事情。

No


The free(3) function takes a void * 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 by malloc(3) and never previously given back to free(3).

日久见人心 2024-10-07 12:46:47

你不能,但你不需要。当您在函数内声明一个变量时,它被称为自动变量,因为它在函数结束时自动被删除(释放其内存)。

如果您想限制自动变量的生命周期,您可以使用 {} 引入作用域,如下所示:

void someFunc( void )
{
    // do some stiff here ...

    { // <- introduce a temporary scope

        char str[6] = {"Hello"}; // this is local to your new scope

        // some processing here ...

    } // <- your array str[] is destroyed here

    // do some more stuff here, str[] has disappeared

}

为了清晰起见,无需额外注释:

void someFunc( void )
{
    // do some stiff here ...

    {

        char str[6] = {"Hello"};

        // some processing here ...

    }

    // do some more stuff here ...

}

在函数内引入新作用域是一个常见的习惯用法,用于清理更广泛范围的无关变量(潜在的错误来源),同时也可以利用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:

void someFunc( void )
{
    // do some stiff here ...

    { // <- introduce a temporary scope

        char str[6] = {"Hello"}; // this is local to your new scope

        // some processing here ...

    } // <- your array str[] is destroyed here

    // do some more stuff here, str[] has disappeared

}

Without the extra comments for clarity:

void someFunc( void )
{
    // do some stiff here ...

    {

        char str[6] = {"Hello"};

        // some processing here ...

    }

    // do some more stuff here ...

}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文