我想要一个指向静态数据的指针数组。例如
void func(...) {
...
static int mysize = initial_size;
static double* d[3] = {new double[mysize], new double[mysize], new double[mysize]};
for(int i=0; i < 3; ++i) {
if(cond) {
//-re-allocate d if necessary.
use d here;
}
else {
use d here; //-since d is static; it persists and so this is justified?
}
}
//-Can I get away with not deleting d here??
}
我的理由是,因为d是指向静态双精度的指针数组;它在函数内部分配一次,所以当一切都超出范围时,它有望被删除?我不知怎的想。这可能是一厢情愿的想法并导致内存泄漏?
也许我最好在这里使用静态C ++向量?我想在这里使用静态,以便在满足某些条件时(例如,如果满足某些条件,例如cond或其否定),重新使用d中先前计算和存储的数据。希望这是有道理的,并提前感谢任何想法。
答案 0 :(得分:3)
删除d
会出错,因为它未与new
分配。但是,由于单个元素 分配了new
,因此您需要小心避免孤立其内存。
答案 1 :(得分:1)
如上所述@AdamLiss,如果在重新分配之前不小心删除现有数组,则可能会在重新分配d(如有必要)步骤中泄漏内存:
void func(...) {
static int mysize = initial_size;
static double* d[3] = {new double[mysize], new double[mysize], new double[mysize]};
for(int i=0; i < 3; ++i) {
if(cond) {
d[i] = new double[2*mysize]; // LEAK!
use d here;
即使你记得像这样删除它:
void func(...) {
static int mysize = initial_size;
static double* d[3] = {new double[mysize], new double[mysize], new double[mysize]};
for(int i=0; i < 3; ++i) {
if(cond) {
delete[] d[i];
d[i] = new double[2*mysize];
有一个错误,因为新的分配可能会抛出一个异常,让d[0]
指向已删除的内存,但没办法告诉它,所以如果d[0]
被解除引用,则调用next函数时将是未定义的行为。
这没关系:
void func(...) {
static int mysize = initial_size;
static double* d[3] = {new double[mysize], new double[mysize], new double[mysize]};
for(int i=0; i < 3; ++i) {
if(cond) {
double* tmp = new double[2*mysize];
std::swap(tmp, d[i]);
delete[] tmp;
但如果您使用向量来管理动态内存,则可以避免此类问题:
void func(...) {
int mysize = initial_size;
typedef std::vector<double> dvec;
static dvec d[3] = {dvec(mysize), dvec(mysize), dvec(mysize)};
for(int i=0; i < 3; ++i) {
if(cond) {
//-re-allocate d if necessary.
d[i].resize(2*mysize);
use d here;
}
else {
use d here;
}
}
}
这样做的另一个好处是能够通过d[i].size()
查询现有大小,而不必在重新分配时手动将旧数组中的元素复制到新数组
答案 2 :(得分:1)
你的代码基本上没问题,但有影响:
内存使用检查工具如purify,insure和valgrind可能会报告更多关于潜在内存泄漏的噪音,但这本身就只是噪音。
static
使得创建线程安全代码变得更加困难 - 让调用者将d
作为函数参数传递给func
,允许特定于线程的副本,应用程序区域特定副本,更轻松的单元测试,无需重新启动过程,以及完整的客户端生命周期控制。
假设您的应用程序引入了一个额外的阶段/阶段,在完成对func()
的调用之后,它会在关闭之前开始执行一些其他内存密集型计算 - 内存仍将被分配。这对您来说可能无关紧要,特别是如果您有足够的虚拟地址空间并且可以将其换成磁盘,但随着代码的发展,这是一个额外的潜在维护问题。