在 Struct 中使用指向 AudioUnitSampleType 的指针时出现内存泄漏 - calloc

发布于 2024-10-16 22:14:05 字数 3081 浏览 2 评论 0原文

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

typedef struct {

    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.

I am coding an audio app for the iphone where I need to use some C code to deal with the audio files. In short, I have a memory leak that is causing the app to crash after so many files have been loaded. The problem is related to a Struct that I create that holds the audio files when read in. The Struct is created as follows;

typedef struct {

    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;

The Struct is then Initialized in the header like this;

   soundStruct                  phraseSynthStructArray[3];

I then attempt to join two files that have been read into phraseSynthStructArray[phrase1Index] and phraseSynthStructArray[phrase2Index] and put the combined file into phraseSynthStructArray[synthPhraseIndex] like this;

- (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;
}

This all works fine and the resulting file is joined and can be used. The isuue I am having is when I allocate the memory here, phraseSynthStructArray[synthPhraseIndex].audioDataLeft = (AudioUnitSampleType *) calloc(totalFramesInFile, sizeof (AudioUnitSampleType)); then next time the method is called, this memory leaks each time and eventually crashes the app. The reason I need to allocate the memory here is because the memory has to be resized to accomodate the joined file which varies in length depending on the size of the input files.

I cannot free the memory after the operation as its needed elsewhere after the method has been called and I have tried to free it before (in joinPhrases method above), but this does not seem to work. I have also tried using realloc to free/reallocate the memory by passing the pointer to the previously allocated memory but this casues a crash stating EXEC_BAD_ACCESS.

I am not a seasoned C programmer and Cannot figure out what I am doing wrong here to cause the leak. I would appreciate some advice to help me track down this issue as I have been banging my head against this for days with no joy. I have read thats its a bad idea to have Pointers in Structs, could this be the root of my problem?

Thanks in advance,
K.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

捶死心动 2024-10-23 22:14:05

也许这有帮助:

- (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]中没有垃圾

Maybe this helps:

- (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;
}

And make sure that there is no garbage in phraseSynthStructArray[synthPhraseIndex]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文