C++ 内部函数调用后是否释放未使用的局部变量?
我正在编写一个应用程序,其中数据可以预处理并写入文件。然后可以再次加载数据,以保存将来运行时的重新计算,但需要在进一步处理之前修改为通用格式 如果没有预处理的数据,程序看起来像:C++ 内部函数调用后是否释放未使用的局部变量?,c++,memory-management,C++,Memory Management,我正在编写一个应用程序,其中数据可以预处理并写入文件。然后可以再次加载数据,以保存将来运行时的重新计算,但需要在进一步处理之前修改为通用格式 如果没有预处理的数据,程序看起来像: void no_preprocess(std::vector<T>& a) { std::vector<P> b = hard_work(a); magic(a, b); } void no_预处理(std::vector&a) { std::vectorb=辛勤工作(
void no_preprocess(std::vector<T>& a)
{
std::vector<P> b = hard_work(a);
magic(a, b);
}
void no_预处理(std::vector&a)
{
std::vectorb=辛勤工作(a);
魔术(a,b);
}
对于预处理的数据:
void foo(std::vector<T>& a, std::string path)
{
std::vector<D> c = read(path);
std::vector<P> b = easy_work(a, c);
// Is c now free?
magic(a, b);
}
void foo(std::vector&a,std::string path)
{
std::vector c=读取(路径);
std::vectorb=容易的工作(a,c); //c现在免费吗? 魔术(a,b); }
一旦
easy\u工作
完成,c
将不再使用。调用magic
后,c
会发生什么情况,也就是说,编译器是否足够聪明,可以自由使用c
?所有自动局部变量在超出范围时都会被销毁<调用magic
后,当函数返回时,code>c将自动销毁所有自动局部变量,当它们超出范围时<调用magic
后,当函数返回时,code>c将自动销毁。当对象退出声明它的作用域时,它将立即销毁,而不是一刻之前
编译器无法在局部变量变为“不再使用”时销毁它们,因为它们可能表示一个锁句柄,需要在块结束前保持活动状态:
{
std::lock_guard<std::mutex> guard(a_mutex);
do_something_on_shared_structure();
// guard is destructed here.
}
(请注意,您不能将其简化为
magic(a,easy_work(a,read(path)))
,因为read()
返回的临时值将在magic()期间继续存在“C++”标准称,“临时”存在于其出现的全部表达式中,并且不再存在,并且调用<代码> MAGICE()/CUT>将是该表达式中的一部分。) < P>在退出声明的范围时,对象将立即被破坏,而不是在一分钟之前。
编译器无法在局部变量变为“不再使用”时销毁它们,因为它们可能表示一个锁句柄,需要在块结束前保持活动状态:
{
std::lock_guard<std::mutex> guard(a_mutex);
do_something_on_shared_structure();
// guard is destructed here.
}
(请注意,您不能将其简化为magic(a,easy_work(a,read(path)))
,因为read()
返回的临时值将在magic()期间继续存在“C++”标准称,“临时”的存在只要它们出现的全部表达式,并且不再存在,并且调用<代码> MAGICE()/CUT>将是该表达式的一部分。它在声明之后不被使用。是的,因为所有C++实现都有一个。顺便说一句,你应该使用@cdhowie哦,亲爱的,我已经纠正了这个问题@你指的是使用std::move
?不是,而是指C++11的许多新特性;值得注意的是,auto
和λ(以及函数式编程风格)。c
甚至不被easy\u work()
使用。它在声明之后不被使用。是的,因为所有C++实现都有一个。顺便说一句,你应该使用@cdhowie哦,亲爱的,我已经纠正了这个问题@你指的是使用std::move
?不是,而是指C++11的许多新特性;特别是auto
和λ(以及函数式编程风格)。回答得很好。尽管我仍然有点惊讶,编译器不允许以这种方式进行优化。在您的锁示例中,是否不清楚a_mutex
是一个全局变量(或者至少不是一个未在范围内声明的变量),因此不能安全地删除,而在我的示例中c
是在范围内声明的,可以安全地删除?@Daniela_mutex
没有被破坏,而是guard
,也就是说,它是一个局部变量。编译器并不假装知道这些类型的作用。例如,在您的例子中,销毁c
还意味着销毁向量中的每个D
对象--如果这些析构函数有副作用,并且您希望销毁延迟到函数结束时,该怎么办?如果您在magic()
中使用对D
对象的引用,并且编译器很早就破坏了这些对象,该怎么办?@Daniel下面是我的意思示例:--在这种情况下,如果编译器提前解构了c
,它将解构通过b
中的P
对象保存引用的所有D
对象。编译器不够聪明,无法解决所有这些问题,如果在不同的翻译单元中定义了easy\u work()
,那么编译器甚至无法解决这些问题,因为它看不到函数体。避免此问题的最简单方法是禁止此类优化。它太容易失败了,回答得很好。尽管我仍然有点惊讶,编译器不允许以这种方式进行优化。在您的锁示例中,是否不清楚a_mutex
是一个全局变量(或者至少不是一个未在范围内声明的变量),因此不能安全地删除,而在我的示例中c
是在范围内声明的,可以安全地删除?@Daniela_mutex
没有被破坏,而是guard
,也就是说,它是一个局部变量。编译器并不假装知道这些类型的作用。例如,在您的例子中,销毁c
还意味着销毁向量中的每个D
对象--如果这些析构函数有副作用,并且您希望销毁延迟到函数结束时,该怎么办?如果您在magic()
中使用对D
对象的引用,并且编译器很早就破坏了这些对象,那么会怎么样?@Daniel下面是我的意思示例:--在这种情况下,如果编译器