如何在C语言中释放动态数组的指针?

5

我在C语言中使用malloc创建了一个动态数组,例如:

myCharArray = (char *) malloc(16);

现在,如果我创建一个这样的函数并将myCharArray传递给它:
reset(char * myCharArrayp)
{
    free(myCharArrayp);
}

这样做行吗?还是我只会释放指向 myCharArrayp 的指针副本,而不是实际的 myCharArray

3个回答

14
你需要明白指针只是一个存储在栈上的变量,它指向内存中的一块区域,本例中是在堆上分配的。你的代码正确释放了堆上的内存。当你从函数返回时,和其他变量(如 int)一样,指针变量也被释放了。
void myFunction()
{
    char *myPointer;     // <- the function's stack frame is set up with space for...
    int myOtherVariable; // <- ... these two variables

    myPointer = malloc(123); // <- some memory is allocated on the heap and your pointer points to it

    free(myPointer); // <- the memory on the heap is deallocated

} // <- the two local variables myPointer and myOtherVariable are freed as the function returns.

1
感谢您详细解释了从头部和堆栈中释放内存的区别。对我来说,如果将“<-”替换为“//”,源代码的着色会更好,更容易阅读。 - Daniel S.

9

这样做可以达到你的预期并释放内存。

我会考虑这样编写函数:

 void reset(char** myPointer) {
     if (myPointer) {
         free(*myPointer);
         *myPointer = NULL;
     }
 }

释放指针后将其设置为NULL,这样可以避免重复使用已释放的指针,因为这是常见的错误源。


实际上,我正在审查一些代码,所以我的示例是一个简化版本。在实际代码中,还有另一行代码:myCharArrayp = NULL; 我知道这不会起作用。但是我开始想知道free是否也无法工作。我猜所有的都必须按照您建议的方式重写。谢谢 :o) - Henrik
Joe的回答解释得很好。指针是存储在堆栈上的变量,函数会获得一份拷贝。这就是为什么上面的例子需要一个指向指针的指针。 - Jeff Foster
2
是的,您需要一个 char **(或 void **),但为什么不在代码中调用 free 后将指针赋值为 NULL 呢?引用一下:“如果 ptr 是 NULL 指针,则不执行任何操作。”所以我会说这个函数有点浪费! - Joe
1
如果我在没有if检查的情况下调用reset(NULL),我将尝试取消引用空指针。之后将其分配为NULL的想法是,被调用者看到NULL值。这样,尝试重用指针失败比仅使用先前释放的地址更可预测。这肯定有点浪费,但我试图建议以牺牲一点为代价换取更多的安全性。在生产中总是可以去掉它。 - Jeff Foster
是的,你关于空指针解引用的问题说得对,我没有仔细读。 - Joe

1

是的,它会起作用。

尽管指针变量的副本将被发送,但它仍将引用正确的内存位置,当调用free时确实会释放该位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接