1

我已将 EXC_BAD_ACCESS 跟踪到以下内存分配和释放。它涉及Xcode中的加速框架。主要问题是此代码处于循环中。如果我强制循环只迭代一次,那么它工作正常。但是当它循环(7 次)时,它会在第二次迭代中导致错误。这看起来不正确吗?

编辑:*添加了实际代码。如果我删除某些部分等,该段就会运行,但似乎内存管理不佳会导致问题

#import <Foundation/Foundation.h>
#include <math.h>
#include <Accelerate/Accelerate.h>

  for(int i = 0; i < 8; i++)
    {

   int XX[M][m];  //M and m are just 2 ints

   for(int kk = 0; kk < M; kk++)
            {
                for (int kk1 = 0; kk1 < m; kk1++)
                {
                    XX[kk][kk1] = [[x objectAtIndex: (kk + kk1 * J)] intValue];  //x is a NSMutableArray of NSNumber objects
                }

            }

            double FreqRes = (double) freqSamp/n;

            NSMutableArray *freqs = [[NSMutableArray alloc] initWithCapacity: round((freqSamp/2 - FreqRes) - 1)];

            int freqSum = 0;

            for(double i = -1 * freqSamp/2; i < (freqSamp/2 - FreqRes); i+= FreqRes)
            {

                [freqs addObject: [NSNumber numberWithInt: i]];

                if(i == 0)
                {
                    freqSum++;
                }

            }

            int num = [x count];
            int log2n = (int) log2f(num);
            int nOver2 = n / 2;

            FFTSetupD fftSetup = vDSP_create_fftsetupD (log2n, kFFTRadix2);

            double ffx[num];

            DSPDoubleSplitComplex fft_data;
            fft_data.realp = malloc(nOver2 * sizeof(double)); //Error usually thrown on this line in the second iteration.  Regardless of what I put there.  If I add an NSLog here it throws the error on that NSLog
            fft_data.imagp = malloc(nOver2 * sizeof(double));


            for (int i = 0; i < n; ++i)
            {
                ffx[i] = [[x objectAtIndex:i] doubleValue];
            }


            vDSP_ctozD((DSPDoubleComplex *) ffx, 2, &fft_data, 1, nOver2);

            vDSP_fft_zripD (fftSetup, &fft_data, 1, log2n, kFFTDirection_Forward);

            for (int i = 0; i < nOver2; ++i)
            {
                fft_data.realp[i] *= 0.5;
                fft_data.imagp[i] *= 0.5;
            }   

            int temp = 1;

            ffx[0] = abs(fft_data.realp[0]);
            for(int i = 1; i < nOver2; i++)
                ffx[i] = sqrt((fft_data.realp[i] * fft_data.realp[i]) + (fft_data.imagp[i] * fft_data.imagp[i]));
            ffx[nOver2] = abs(fft_data.imagp[0]);
            for(int i = nOver2-1; i > 0; i--)
            {
                ffx[nOver2 + temp] = sqrt((fft_data.realp[i] * fft_data.realp[i]) + (fft_data.imagp[i] * fft_data.imagp[i]));
                temp++;
            }

            //clear Fxx and freqs data
            vDSP_destroy_fftsetupD(fftSetup);
            free(fft_data.imagp);
            free(fft_data.realp);
            [freqs release];
}
4

2 回答 2

2

您的问题可能是您将 malloc 转换为一个值。当您标记此 c 时,我假设您正在使用 c 进行编译,在这种情况下,您应该看到上一个问题的答案,即为什么使用 malloc 进行强制转换是不好的:

https://stackoverflow.com/a/1565552/1515720

在不包含 stdlib.h 的情况下使用强制转换时会出现不可预知的运行时错误。

所以你这边的错误不是演员表,而是忘记包含stdlib.h。编译器可能会假设 malloc 是一个返回 int 的函数,因此将 malloc 实际返回的 void* 指针转换为 int,然后由于显式转换而转换为您的指针类型。在某些平台上,int 和指针可能占用不同的字节数,因此类型转换可能会导致数据损坏。

无论如何,正如答案所说,你不应该铸造 MALLOC 返回,因为 void* 被安全地隐式转换为你分配给它的任何东西。

正如另一位回答者所说:

vDSP_destroy_fftsetupD(fftSetup);

也可以释放您意外分配的内存。

于 2012-07-25T00:35:48.837 回答
2

析构函数是否有可能DSPDoubleSplitComplex释放这两个分配的块?

也可能是您只能在进程的生命周期vDSP_create_fftsetupD内调用vDSP_destroy_fftsetupD 一次

于 2012-07-25T00:37:23.293 回答