C - 释放指向指针的指针

4
在我的代码中,我分配了一些二维数组,需要释放它们。然而,每当我认为我已经掌握了指针的概念时,它们总是会让我感到惊讶,因为它们并不像我所期望的那样工作 ;) 那么,有人能告诉我如何处理这种情况吗? 这是我为我的指针分配内存的方式:
typedef struct HRTF_ {
  kiss_fft_cpx freqDataL[NFREQ]
  kiss_fft_cpx freqDataR[NFREQ]
  int nrSamples;
  char* fname;
} HRTF;

HRTF **_pHRTFs = NUL;
int _nHRTFs = 512;

_pHRTFs = (HRTF**) malloc( sizeof(HRTF*) *_nHRTFs );

int i = _nHRTFs;
while( i > 0 )
  _pHRTFs[--i] = (HRTF*) malloc( sizeof( HRTF ) );

// Load data into HRTF struct

以下是我认为应该释放已使用内存的方法:

if( _pHRTFs != NULL )
{
  __DEBUG( "Free mem used for HRTFs" );
  for( i = 0; i < _nHRTFs; ++i )
  {
    if( _pHRTFs[i] != NULL )
    {
      char buf[64];
      sprintf( buf, "Freeing mem for HRTF #%d", i );
      __DEBUG( buf );
      free( _pHRTFs[i] );
    }
  }
  __DEBUG( "Free array containing HRTFs" );
  free( _pHRTFs );
}

释放单个_pHRTFs[i]是可行的,最后一条__DEBUG语句已经打印出来了,但是最后一条free( _pHRTFs )语句导致了段错误。为什么呢?

没关系 - 在最后一条free( _pHRTFs )之后添加一个调试语句显示,这段代码实际上是有效的,我的问题在其他地方。感谢您的时间!

Jonas


3
代码看起来没问题。你能否实际上对分配和释放之间的所有内容进行注释,并查看是否仍然发生? - cnicutar
char *fname 是如何使用的?如果你为它分配了内存,在释放包含结构体的数组之前,应该先释放它。 - Itamar Katz
代码看起来没问题 - 但在C代码中请不要对malloc的结果进行强制转换 - 这是不必要的,而且可能掩盖了编译器警告本应揭示的错误。 - Paul R
我怀疑在分配和释放资源之间发生了一些堆栈损坏 - 尝试在valgrind下运行代码。 - Paul R
1
代码表面上看起来还不错,假设 _nHRTFs 的值相同(尽管有很多被认为是不好的形式:将 malloc 的结果强制转换,不检查 malloc 是否成功,使用 sizeof(T) 而不是 sizeof *var,使用 sprintf 而不是 snprintf,以前导下划线命名事物)。 - jamesdlin
2个回答

2
代码没问题。我已经尝试运行它,结果很好。以下是我测试过的代码(我用int替换了未知数据类型)和输出结果,表明这里没有任何问题。你得到的错误是因为其他原因。
#include <stdio.h>
#include <stdlib.h>

typedef struct HRTF_ {
      int freqDataL[10];
      int freqDataR[10];
      int nrSamples;
      char* fname;
} HRTF;

HRTF **_pHRTFs = NULL;
int _nHRTFs = 512;

int main(){
    printf("allocatingi\n");
    _pHRTFs = (HRTF**) malloc( sizeof(HRTF*) *_nHRTFs );

    int i = _nHRTFs;
    while( i > 0 )
          _pHRTFs[--i] = (HRTF*) malloc( sizeof( HRTF ) );

    printf("Allocation complete. Now deallocating\n");
    for( i = 0; i < _nHRTFs; ++i )
    {
        if( _pHRTFs[i] != NULL )
        {
            char buf[64];
            sprintf( buf, "Freeing mem for HRTF #%d", i );
            //__DEBUG( buf );
            free( _pHRTFs[i] );
        }
    }
    printf("complete without error\n");
    return 0;
}

并输出:

adnan@adnan-ubuntu-vm:desktop$ ./a.out 
allocatingi
Allocation complete. Now deallocating
complete without error

1

内存分配和释放看起来没问题。我也将上面的代码编译成int类型并得到了以下输出。问题出在其他地方。

Freeing mem for HRTF #0
Freeing mem for HRTF #1
......
Freeing mem for HRTF #509
Freeing mem for HRTF #510
Freeing mem for HRTF #511

请编辑您的答案,检查是否可以缩短输出。 - tuxuday
我希望在这种情况下获得完整的输出,以证明正确的free()。即使我不打算写长篇文章。 - Manik Sidana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接