【发布时间】:2011-05-23 22:13:38
【问题描述】:
如果我将值作为参数传递给特定函数,那么该函数会在函数执行结束时释放该参数的内存吗?
如果我将指针或引用作为参数传递,如果函数释放指针参数的内存会发生什么?会影响函数外的变量吗?
【问题讨论】:
标签: c++ stack memory-management
如果我将值作为参数传递给特定函数,那么该函数会在函数执行结束时释放该参数的内存吗?
如果我将指针或引用作为参数传递,如果函数释放指针参数的内存会发生什么?会影响函数外的变量吗?
【问题讨论】:
标签: c++ stack memory-management
在第一种情况下,内存将被“释放”(实际上堆栈指针会增加)。如果这不是 POD 类型的变量析构函数被调用,那么如果在堆中分配的内存将从堆中释放。
在第二种情况下,指针引用的值不会被释放 - 只会释放指针的内存。
【讨论】:
对于第 1 点,它取决于参数的类型。通过例如按值的“字符串”将执行隐式复制,并且当变量(函数参数)超出范围时,复制使用的内存将被释放。对于您自己的类型,这不会自动发生 - 您需要正确设置构造和销毁。
对于第二个 - 是的,使用指针解除分配将影响它所寻址的内存 - 在函数内部和外部。
澄清第二点:
void func(char *someMemory) {
delete[] someMemory;
}
//...
char *myArray = new char[100];
func(myArray);
...将删除分配的内存 - 在调用 func 失败后使用 myArray。
【讨论】:
如果您在堆栈上传递一个值或指针,则保存该值所需的内存将分配在堆栈上...
堆栈的工作方式可以继续“分配”更多内存,但必须以相反的顺序“释放”。
所以:
void f(int *ptr, int v)
{
// Do something
}
当您调用 f() 时,ptr 和 v 的值被“推送”到堆栈上,即神奇地创建了足够的内存来保存这些值。当函数返回时,堆栈会以另一种方式调整,从某种意义上说,它们是从堆栈中“弹出”的。
这种推送和弹出对原始指针或值没有影响。所以:
ptr++;
不会影响调用函数持有的指针的值。
如果您取消引用 *ptr,则您正在访问从函数外部可见的相同数据的指针。如果你释放()指针,这会影响从函数外部看到的内容。因此,当您传递一个指针时,指针指向的原始数据没有副本,但实际指针有一个副本。指针按值传递。
【讨论】: