【问题标题】:Memory Leak when using Pointer to AudioUnitSampleType in Struct - calloc在 Struct 中使用指向 AudioUnitSampleType 的指针时发生内存泄漏 - calloc
【发布时间】:2011-06-24 18:26:02
【问题描述】:

我正在为 iphone 编写一个音频应用程序,我需要使用一些 C 代码来处理音频文件。简而言之,在加载了这么多文件后,我的内存泄漏导致应用程序崩溃。问题与我创建的一个结构有关,该结构在读入时保存音频文件。结构的创建如下;

typedef 结构 {

    UInt32               frameCount;         // the total number of frames in the audio data
    UInt32               sampleNumber;       // the next audio sample to play
    BOOL                 isStereo;           // set to true if there is data audioDataRight member
    AudioUnitSampleType  *audioDataLeft;     // complete left channel of audio data read from file
    AudioUnitSampleType  *audioDataRight;    // complete right channel of audio data read file

} soundStruct, *soundStructPtr;

然后像这样在标头中初始化结构;

   soundStruct                  phraseSynthStructArray[3];

然后我尝试加入两个已读入phraseSynthStructArray[phrase1Index]phraseSynthStructArray[phrase2Index] 的文件,并像这样将合并后的文件放入phraseSynthStructArray[synthPhraseIndex]

- (BOOL) joinPhrases:(UInt32)phrase1Index phrase2Index:(UInt32)phrase2Index synthPhraseIndex:(UInt32)synthPhraseIndex{

    // get the combined frame count
    UInt64 totalFramesInFile = inArray[phrase1Index].frameCount + inArray[phrase2Index].frameCount;

    //now resize the synthPhrase slot buffer to be the same size as both files combined
    //  phraseOut is used to hold the combined data prior to it being passed into the soundStructArray slot

    free(phraseSynthStructArray[synthPhraseIndex].audioDataLeft);
    phraseSynthStructArray[synthPhraseIndex].audioDataLeft = NULL;
    phraseSynthStructArray[synthPhraseIndex].frameCount = 0;
    phraseSynthStructArray[synthPhraseIndex].frameCount = totalFramesInFile;
    phraseSynthStructArray[synthPhraseIndex].audioDataLeft = (AudioUnitSampleType *) calloc(totalFramesInFile, sizeof (AudioUnitSampleType));


        for (UInt32 frameNumber = 0; frameNumber < inArray[phrase1Index].frameCount; ++frameNumber) {
            phraseSynthStructArray[synthPhraseIndex].audioDataLeft[frameNumber] = phraseSynthStructArray[phrase1Index].audioDataLeft[frameNumber];
        }


        UInt32 sampleNumber=0;
        for (UInt32 frameNumber = phraseSynthStructArray[phrase1Index].frameCount; frameNumber < totalFramesInFile; ++frameNumber) {
            phraseSynthStructArray[synthPhraseIndex].audioDataLeft[frameNumber] = phraseSynthStructArray[phrase2Index].audioDataLeft[sampleNumber];
            sampleNumber++;
        }


    return YES;
}

这一切正常,生成的文件已加入并可以使用。我遇到的问题是当我在这里分配内存时,phraseSynthStructArray[synthPhraseIndex].audioDataLeft = (AudioUnitSampleType *) calloc(totalFramesInFile, sizeof (AudioUnitSampleType)); 然后下次调用该方法时,每次都会泄漏此内存并最终使应用程序崩溃。我需要在这里分配内存的原因是因为必须调整内存的大小以容纳长度根据输入文件的大小而变化的连接文件。

在调用该方法后,我无法在操作后释放内存,因为它在其他地方需要,并且我之前尝试过释放它(在上面的 joinPhrases 方法中),但这似乎不起作用。我还尝试使用 realloc 通过将指针传递给先前分配的内存来释放/重新分配内存,但这会导致崩溃,说明 EXEC_BAD_ACCESS。

我不是一个经验丰富的 C 程序员,并且无法弄清楚我在这里做错了什么导致泄漏。我会很感激一些建议来帮助我找出这个问题,因为我几天来一直在努力解决这个问题,没有任何乐趣。我已经读过在结构中有指针是个坏主意,这可能是我问题的根源吗?

提前致谢, K.

【问题讨论】:

  • 您使用过泄漏工具吗?

标签: iphone pointers memory-leaks struct audiounit


【解决方案1】:

也许这会有所帮助:

- (BOOL) joinPhrases:(UInt32)phrase1Index phrase2Index:(UInt32)phrase2Index synthPhraseIndex:(UInt32)synthPhraseIndex{

    // get the combined frame count
    UInt64 totalFramesInFile = inArray[phrase1Index].frameCount + inArray[phrase2Index].frameCount;

. . .

    void* old_ptr = phraseSynthStructArray[synthPhraseIndex].audioDataLeft;
    phraseSynthStructArray[synthPhraseIndex].audioDataLeft = (AudioUnitSampleType *) calloc(totalFramesInFile, sizeof (AudioUnitSampleType));
    if( old_ptr ) free(old_ptr);

. . .


    return YES;
}

并确保phraseSynthStructArray[synthPhraseIndex]中没有垃圾

【讨论】:

  • 感谢您的 cmets max。我已经尝试过了,它不会崩溃,一个好兆头!但是,我在另一种方法中做类似的事情,它像这样传递短语SynthStructArray: - (BOOL) readAudioFilesIntoMemory:(soundStructPtr)inArray 并像以前一样分配内存:inArray[audioFile].audioDataLeft =(AudioUnitSampleType *) calloc (totalFramesInFile, sizeof (AudioUnitSampleType));但是,如果我在这里尝试使用您的建议,它会崩溃并指出“malloc:对象 0xb716000 的 *** 错误:未分配被释放的指针”。任何想法为什么会发生这种情况?
  • 是的,我有个主意。我写道:'确保phraseSynthStructArray [synthPhraseIndex] 中没有垃圾'。这意味着当你声明一个指针(即使它在一个结构中)时,它通常包含垃圾,它没有指向任何地方。这就是为什么你必须用 NULL 来初始化你的指针以确保它们没有指向某个地方。例如。 soundStruct s; s.audioDataLeft = NULL; s.audioDataRight = NULL;
  • 我已经尝试过了,但我仍然有内存问题。如上所述,我应该设置 s.audioDataLeft = NULL。这是否意味着在这样做时我确保 if( old_ptr ) free(old_ptr);永远不会被调用,因此没有内存清理。为这些简单的问题道歉,但我觉得在这个阶段我做的事情根本上是错误的。你有什么其他建议可以帮助我找到这个问题。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 2014-05-10
  • 2014-08-13
  • 2015-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
相关资源
最近更新 更多