LibAIFF CloseFile: освобожденный указатель не был выделен случайно

Я написал фрагмент кода, который пытается найти в каталоге и его подпапках два файла AIFF и использовать библиотеку LibAIFF для импорта, а затем выполнить некоторые операции с ними.

Часть 1: Поиск в каталоге для файлов

Для этой части программы мне нужно искать файлы (которые можно рассматривать как идентичные файлы AIFF, за исключением различий в именах файлов) с известными именами (например, SineSweepA.aiff и SineSweepB.aiff), а затем создать абсолютный путь к нему (о длине которого я не знаю), так как моя программа должна работать на разных компьютерах, где AIFF могут быть расположены в разных подпапках внутриMainDirectory - см. код ниже), но знайте, что он будет содержать не более 200 символов). Я могу сделать это успешно и последовательно, используя следующий фрагмент кода:

void file_search(char* parentDir, char* subFolder, char* filenamePrefix, char* tempString, char* tempFilepath, int* foundFlag, int* level);
int32_t *import_sweeps(char* sweepFilepath, uint64_t* numSamples, int* numChannels, double* samplingRate, int* bitDepth, int* segmentSize, int* importFlag);

int main()
{
    ...
    char MainDirectory[200] = "/Users/rrr/Documents/Foldername1/";
    char tempFilepath[200], tempFilepathR[200], parentDir[200], filenamePrefix[200], subFolder[200], tempString[200]; 
    int level = 0, foundFlag = 0;
    int numChannels = 0;
    int bitDepth;
    int segmentSize;
    int importFlag = 0;
    int32_t *sweepRfile = NULL;
    uint64_t numSamples = 0, numSamplesR = 0;
    unsigned long templen;
    double samplingRate = 0.0;
    char *sweepFilepath = NULL, *sweepFilepathR = NULL; // Allocated to specific size later
    strcpy(parentDir, MainDirectory);
    strcat(parentDir, "SubFolderName1/");
    strcpy(tempFilepathR, parentDir);
    strcpy(filenamePrefix, "KnownFilenamePrefix1");

    // file_search() searches for a specific file with a known name and constructs the absolute path to the file and stores it in tempFilepathR. The function is shown further below.
    file_search(parentDir, subFolder, filenamePrefix, tempString, tempFilepath, &foundFlag, &level);

    if (foundFlag)
    {
        sprintf(tempFilepath, "%s%s/KnownFilenamePrefix1%s.aiff", parentDir, subFolder, subFolder);
        sprintf(tempFilepathR, "%s%s/KnownFilenamePrefix2%s.aiff", parentDir, subFolder, subFolder);
    }
    ...

    (to be continued in Part 2 of my question below)
}

void file_search(char* dir, char* subfolder, char* fileprefix, char* filename, char* filepath, int*flag, int* level)
{
    DIR *dp;
    struct dirent *entry; // entry is a pointer to the structure "dirent" defined in <dirent.h>
    struct stat statbuf; // the structure "stat" is defined in <stat.h>
    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"Cannot open directory: %s\n", dir);
        return;
    }
    chdir(dir); // this sets the working directory to the string pointed to by "dir"
    while((entry = readdir(dp)) != NULL)
    {
        lstat(entry->d_name, &statbuf);
        if(S_ISDIR(statbuf.st_mode)) // Tests for a directory
        {
            // Found a directory
            if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0)
            {
                // Ignore . and ..
                continue;
            }

            if(level[0] < 1)
            {
                // Proceed down one level and search again
                strcpy(subfolder,entry->d_name);
                level[0] = level[0] + 1;

                // Recursive function call
                file_search(entry->d_name, subfolder, fileprefix, filename, filepath, postfilepath, flag, level);

                level[0] = level[0] - 1;

                if(flag[0] == 1)
                {
                    // Exit loop if a file was found at a lower level
                    break;
                }
            }
        }
        else
        {
            sprintf(filename, "%s%s.aiff", fileprefix, subfolder);
            if(strcmp(entry->d_name,filename) == 0)
            {
                // File found. Construct absolute path to file
                sprintf(filepath, "%s%s/%s", filepath, subfolder, filename); // Pass filepath outside
                flag[0] = 1; //Appropriate file found
                break;
            }
        }
    }
    chdir("..");
    closedir(dp);
}

Таким образом, используя приведенный выше код, я могу успешно искать два файла AIFF с заданными именами файлов путем поиска в подпапках с известнымMainDirectoryпостроить их абсолютные пути и сохранить их вtempFilepath а такжеtempFilepathR, Следующим шагом является импорт этих двух файлов, и именно здесь я сталкиваюсь с проблемой.

Часть 2. Импорт файлов

Проблема, с которой я сталкиваюсь, заключается в следующем: Я реализовал библиотеку LibAIFF для импорта файлов. Проблема заключается в том, что если я запускаю программу, скажем, N раз, то при некоторых запусках первый файл импортируется, но не второй, при других запусках импортируется второй, но не первый (обратите внимание, что если первый не т импортируется, программа останавливается).Прежде чем объяснить ошибку, пожалуйста, знайте, что с файлами AIFF проблем нет, ради этой проблемы вы можете предположить, что они идентичны, и что даже их абсолютные пути и имена файлов идентичны, за исключением того, что у каждого есть суффиксA.aiff и другиеB.aiff, Эти пути к файлам хранятся в виде строк в идентично определенных переменных (tempFilepath а такжеtempFilepathR).

Вот остальная часть необходимой части моего кода, продолженная сверху

int main()
{
    // Continued from above
    ...

    // Copy over exact file paths (I had to do this because the function AIFF_OpenFile which is part of the LibAIFF library and shown below refused to accept a statically allocated char variable such as tempFilepath)

        templen = strlen(tempFilepathR); // tempFilepath and tempFilepathR always have the same length
        sweepFilepath = malloc(templen + 1);
        strcpy(sweepFilepath, tempFilepath);

        // Proceed to import the FIRST AIFF (returned to sweepRfile from import_sweeps())
        sweepRfile = import_sweeps(sweepFilepath, &numSamples, &numChannels, &samplingRate, &bitDepth, &segmentSize, &importFlag);
        if (importFlag) // The import was successful
        {
            free(sweepFilepath);
            // Do some processing with the successfully imported AIFF
            free(sweepRfile);
        }
        else // The import was unsuccessful and sweepRfile (which is usually malloc'ed in the import_sweeps() function is not malloc'ed
        {
            free(sweepFilepath);
        }

        // Now for the SECOND AIFF (I can overwrite a lot of the variables used for the first AIFF because I don't need them)
        sweepFilepathR = malloc(templen + 1); // templen is assigned above
        strcpy(sweepFilepathR, tempFilepathR);

        // Proceed to import the SECOND AIFF (returned to sweepRfile from import_sweeps())
        sweepRfile = import_sweeps(sweepFilepathR, &numSamplesR, &numChannels, &samplingRate, &bitDepth, &segmentSize, &importFlag);
        if (importFlag) // The import was successful
        {
            free(sweepFilepathR);
            // Do some processing with the successfully imported AIFF
            free(sweepRfile);
        }
        else // The import was unsuccessful and sweepRfile (which is usually malloc'ed in the import_sweeps() function is not malloc'ed
        {
            free(sweepFilepathR);
        }
    ...
    // Rest of code in main is irrelevant because it doesn't even get there.
}

Разрыв всегда происходит внутри функции import_sweeps () (иногда для первого AIFF, а иногда для второго). Функция показана ниже

int32_t *import_sweeps(char* sweepFilepath, uint64_t* numSamples, int* numChannels, double* samplingRate, int* bitDepth, int* segmentSize, int* importFlag)
{
    // Initialize files for importing */
AIFF_Ref fileref;

// Import Routine */
fileref = AIFF_OpenFile(sweepFilepath, F_RDONLY);
if(fileref)
{
    // File opened successfully. Proceed to intialize files for getting information about AIFF file
    uint64_t nSamples;
    int nSamplePts, channels, bitsPerSample, segSize, temp;
    double smpr;

    // Get AIFF file format details
    temp = AIFF_GetAudioFormat(fileref, &nSamples, &channels, &smpr, &bitsPerSample, &segSize);
    if (temp < 1) {
        fprintf(stderr,"Error getting audio format.\n");
        AIFF_CloseFile(fileref);
        return (int32_t) 0;
    }
    else
    {
        numSamples[0] = nSamples;
        samplingRate[0] = smpr;
        numChannels[0] = channels;
        bitDepth[0] = bitsPerSample;
        segmentSize[0] = segSize;
        nSamplePts = ((int) nSamples)*channels;
        int32_t *samples = malloc((nSamplePts+1) * sizeof(int32_t));

        // Read AIFF
        temp = AIFF_ReadSamples32Bit(fileref, samples, nSamplePts);
        if (temp != -1)
        {
            AIFF_CloseFile(fileref);
            importFlag[0] = 1;
            return samples;
        }
        else
        {
            fprintf(stderr,"Unable to read AIFF.\n");
            AIFF_CloseFile(fileref);
            return (int32_t) 0;
        }
    }
}
else
{
    fprintf(stderr,"Unable to open AIFF file.\n");
}
return (int32_t) 0;
}

Внутри import_sweeps () выше файл AIFF ВСЕГДА успешно читается при вызове функцииAIFF_ReadSamples32Bit(fileref, samples, nSamplePts);, Следовательно, значение temp никогда не равно -1. Всякий раз, когда возникает ошибка (как описано выше, и я приведу реальное сообщение об ошибке ниже), она ВСЕГДА возникает, когда пытаетсяAIFF_CloseFile(fileref);.

Ниже показаны функцииAIFF_ReadSamples32Bit а такжеAIFF_CloseFile как определено в библиотеке LibAIFF.

int AIFF_ReadSamples32Bit(AIFF_Ref r, int32_t * samples, int nSamplePoints)
{
int n = nSamplePoints;
void *buffer;
int i, j;
size_t h;
size_t len;
int segmentSize;
int32_t *dwords;
int16_t *words;
int8_t *sbytes;
uint8_t *inbytes;
uint8_t *outbytes;
uint8_t x, y, z;

if (!r || !(r->flags & F_RDONLY))
    return -1;
if (n % (r->nChannels) != 0)
    return 0;

if (n < 1 || r->segmentSize == 0) {
    if (r->buffer) {
        free(r->buffer);
        r->buffer = NULL;
        r->buflen = 0;
    }
    return -1;
}
segmentSize = r->segmentSize;
len = (size_t) n * segmentSize;

if ((r->buflen) < len) {
    if (r->buffer)
        free(r->buffer);
    r->buffer = malloc(len);
    if (!(r->buffer)) {
        return -1;
    }
    r->buflen = len;
}
buffer = r->buffer;

h = AIFF_ReadSamples(r, buffer, len);
if (h < (size_t) segmentSize) {
    free(r->buffer);
    r->buffer = NULL;
    r->buflen = 0;
    return 0;
}
n = (int) h;
if (n % segmentSize != 0) {
    free(r->buffer);
    r->buffer = NULL;
    r->buflen = 0;
    return -1;
}
n /= segmentSize;

switch (segmentSize) {
case 4:
    dwords = (int32_t *) buffer;
    for (i = 0; i < n; ++i)
        samples[i] = dwords[i];
    break;
case 3:
    inbytes = (uint8_t *) buffer;
    outbytes = (uint8_t *) samples;
    n <<= 2;    /* n *= 4 */
    j = 0;

    for (i = 0; i < n; i += 4) {
        x = inbytes[j++];
        y = inbytes[j++];
        z = inbytes[j++];
#ifdef WORDS_BIGENDIAN
        outbytes[i] = x;
        outbytes[i + 1] = y;
        outbytes[i + 2] = z;
        outbytes[i + 3] = 0;
#else
        outbytes[i] = 0;
        outbytes[i + 1] = x;
        outbytes[i + 2] = y;
        outbytes[i + 3] = z;
#endif
    }

    n >>= 2;
    break;
case 2:
    words = (int16_t *) buffer;
    for (i = 0; i < n; ++i) {
        samples[i] = (int32_t) (words[i]) << 16;
    }
    break;
case 1:
    sbytes = (int8_t *) buffer;
    for (i = 0; i < n; ++i) {
        samples[i] = (int32_t) (sbytes[i]) << 24;
    }
    break;
}

return n;
}

а также

int AIFF_CloseFile(AIFF_Ref ref)
{
int r;

if (!ref)
    return -1;
if (ref->flags & F_RDONLY) {
    AIFF_ReadClose(ref); // BREAK OCCURS HERE EVERYTIME
    r = 1;
} else if (ref->flags & F_WRONLY) {
    r = AIFF_WriteClose(ref);
} else {
    r = -1;
}

return r;
}   

Перерыв происходит вAIFF_ReadClose(ref); КАЖДЫЙ РАЗ. Так что я также показал эту функцию ниже.

static void AIFF_ReadClose(AIFF_Ref r)
{
if (r->buffer)
    free(r->buffer);
if (r->buffer2)
    free(r->buffer2);  // THIS IS WHERE THE BREAK OCCURS EVERYTIME
Unprepare(r);
fclose(r->fd);
free(r);
return;
}

Перерыв всегда происходит, как показано выше. Ниже приводитсясообщение об ошибке: (25693,0x7fff7db87310) malloc:* ошибка для объекта 0x4000000000000000: освобожденный указатель не выделен * установить точку останова в malloc_error_break для отладки

Таким образом, в основном, вышеупомянутая ошибка происходитнепредсказуемо, Когда этого не происходит, мой код работает отлично.Любая помощь относительно того, как я мог бы решить эту проблему, очень ценится.

Если кто-либо захочет загрузить библиотеку LIBAIFF для дальнейшего исследования и помочь мне, ссылка на библиотеку:http://aifftools.sourceforge.net/libaiff/.

Спасибо заранее за любые предложения!

Ответы на вопрос(1)

Ваш ответ на вопрос