C ++函数中指向静态双精度的指针数组

时间:2012-05-24 22:27:57

标签: c++ c static

我想要一个指向静态数据的指针数组。例如

  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中先前计算和存储的数据。希望这是有道理的,并提前感谢任何想法。

3 个答案:

答案 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()的调用之后,它会在关闭之前开始执行一些其他内存密集型计算 - 内存仍将被分配。这对您来说可能无关紧要,特别是如果您有足够的虚拟地址空间并且可以将其换成磁盘,但随着代码的发展,这是一个额外的潜在维护问题。