Утечка памяти при использовании Pointer to AudioUnitSampleType в Struct - calloc - PullRequest
0 голосов
/ 10 февраля 2011

Я кодирую аудиоприложение для 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 и не могу понять, что я делаюнеправильно здесь, чтобы вызвать утечку.Я был бы признателен за совет, чтобы помочь мне отследить эту проблему, так как я бился головой об этом в течение многих дней без радости.Я читал, что это плохая идея иметь указатели в структурах, это может быть корнем моей проблемы?

Заранее спасибо, К.

1 Ответ

0 голосов
/ 10 февраля 2011

Может быть, это поможет:

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

И убедитесь, что в фразе SynthStructArray [synthPhraseIndex]

нет мусора
...