简体   繁体   English

C内存管理问题

[英]C Memory Management Issue

I have traced an EXC_BAD_ACCESS to the following allocation and deallocation of memory. 我已经跟踪了一个EXC_BAD_ACCESS来分配和释放内存。 It involves the accelerate framework in Xcode. 它涉及Xcode中的加速框架。 The main issue is that this code is in a loop. 主要问题是这段代码是循环的。 If i force the loop to only iterate once then it works fine. 如果我强制循环只迭代一次然后它工作正常。 But when it loops (7 times) it causes an error on the second iteration. 但是当它循环(7次)时,它会在第二次迭代时导致错误。 Does any of this look incorrect? 这看起来有什么不对吗?

EDIT: *added actual code. 编辑:*添加实际代码。 This segment runs if I remove certain parts and such but seems to have poor memory management which results in issues 如果我删除某些部件,但是这个部分会运行,但似乎内存管理不佳会导致问题

#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];
}

Your problem could be that you are casting malloc to a value. 您的问题可能是您正在将malloc转换为值。 As you're tagging this c, I'm assuming that you are compiling in c in which case you should see this answer to a previous question as to why casting with malloc is bad: 当你正在标记这个c时,我假设你正在编译c,在这种情况下你应该看到前一个问题的答案,为什么使用malloc进行转换是坏的:

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

you can get an unpredictable runtime error when using the cast without including stdlib.h. 在不使用stdlib.h的情况下使用强制转换时,您可能会遇到不可预测的运行时错误。

So the error on your side is not the cast, but forgetting to include stdlib.h. 所以你身边的错误不是强制转换,而是忘记包含stdlib.h。 Compilers may assume that malloc is a function returning int, therefore converting the void* pointer actually returned by malloc to int and then to your your pointer type due to the explicit cast. 编译器可能会认为malloc是一个返回int的函数,因此将malloc实际返回的void *指针转换为int,然后由于显式转换而转换为指针类型。 On some platforms, int and pointers may take up different numbers of bytes, so the type conversions may lead to data corruption. 在某些平台上,int和指针可能占用不同的字节数,因此类型转换可能会导致数据损坏。

Regardless though, as the answer says, YOU SHOULD NOT BE CASTING MALLOC RETURNS, because void*'s are safely implicitly converted to whatever you are assigning it to. 无论如何,正如答案所说,你不应该进行MALLOC RETURNS,因为void *被安全地隐式转换为你指定的任何东西。

As another answerer stated: 正如另一位回答者所说:

vDSP_destroy_fftsetupD(fftSetup);

Could be also free'ing the memory you allocated on accident. 也可以释放你在事故中分配的记忆。

Any chance the destructor of DSPDoubleSplitComplex is freeing up those two allocated blocks? DSPDoubleSplitComplex的析构函数DSPDoubleSplitComplex有可能释放这两个分配的块?

It could also be that you are only allowed to call vDSP_create_fftsetupD and vDSP_destroy_fftsetupD once during your process's lifetime 也可能只允许您在进程的生命周期内调用vDSP_create_fftsetupDvDSP_destroy_fftsetupD 一次

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM