【发布时间】:2010-04-08 07:18:06
【问题描述】:
这是一个(人为)使用返回匿名结构并执行“某些”有用的函数的示例:
#include <iostream>
template<typename T>
T* func(T* t, float a, float b) {
if(!t) {
t = new T;
t->a = a;
t->b = b;
} else {
t->a += a;
t->b += b;
}
return t;
}
struct {
float a, b;
}* foo(float a, float b) {
if(a==0) return 0;
return func(foo(a-1,b), a, b);
}
int main() {
std::cout << foo(5,6)->a << std::endl;
std::cout << foo(5,6)->b << std::endl;
void* v = (void*)(foo(5,6));
//[1] delete f now because I know struct is floats only.
float* f = (float*)(v);
std::cout << f[0] << std::endl;
std::cout << f[1] << std::endl;
delete[] f;
return 0;
}
我想讨论几点:
- 很明显,这段代码泄漏了,在不知道底层结构定义是什么的情况下,无论如何我不能泄漏吗?见评论 [1]。
- 我必须返回一个指向匿名结构的指针,这样我才能在模板化函数
func中创建对象的实例,我可以在不返回指针的情况下做类似的事情吗? - 我想最重要的是,它有任何(现实世界)用途吗?正如上面给出的示例一样,这显然是人为设计的。
顺便说一句,函数foo(a,b) 所做的是返回一个包含两个数字的结构体,即从1 到a 的所有数字的总和以及a 和b 的乘积。
也许new T 行可以使用 boost::shared_ptr 以某种方式避免泄漏,但我还没有尝试过。那行得通吗?
我想我只是想将匿名结构作为浮点数组删除,例如 float* f = new float[2]。正如下面的评论所暗示的,这可能是错误的,那么可以做些什么呢?我可以删除吗?
我可以在 VS2008 上“按原样”编译和运行此代码,也许 VS 可能正在使用一些非标准扩展,但它确实运行并给出 15 和 30 作为答案。
从答案中我相信这个装置是 VS2008 特定的实体,它不符合标准,因此不可移植。不过太糟糕了,我很想看看 Stackoverflow 或 Boost 的人想出了什么巫术,如果这在他们的武器库中:)。谢谢大家。
【问题讨论】:
-
delete[]在用new分配的内存上?哎哟! -
我知道,我只是想将匿名结构删除为浮点数组,类似于 float* f = new float[2]。
-
我几乎肯定你根本做不到,所以有没有用并不重要。
-
@Dennis Zickefoose :我可以在 VS2008 上编译和运行它,可能会使用一些非标准扩展。但我很肯定它适用于 VS2008。
-
尝试在delete[]之后做点什么;那里可能发生任何事情。
标签: c++ templates memory-leaks anonymous-types