LibAIFF CloseFile: el puntero liberado no se asignó ocurre aleatoriamente

He escrito un fragmento de código que intenta buscar en un directorio y sus subcarpetas dos archivos AIFF y usar la biblioteca LibAIFF para importar y luego realizar algunas operaciones de procesamiento en ellos.

Parte 1: buscar en el directorio los archivos

Para esta parte del programa, necesito buscar los archivos (que pueden considerarse como archivos AIFF idénticos, excepto por una diferencia en sus nombres de archivo) con nombres conocidos (por ejemplo, SineSweepA.aiff y SineSweepB.aiff) y luego construir el ruta absoluta a la misma (la longitud de la cual no estoy al tanto (ya que mi programa necesita trabajar en diferentes computadoras donde los AIFF pueden ubicarse dentro de diferentes subcarpetas dentro de unMainDirectory - vea el código a continuación) pero sabe que tendrá menos de 200 caracteres de longitud). Puedo hacer esto exitosamente y consistentemente usando el siguiente código:

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

Por lo tanto, al usar el código anterior, puedo buscar con éxito dos archivos AIFF con nombres de archivo buscados a través de subcarpetas con un conocidoMainDirectory, construir sus caminos absolutos y almacenarlos entempFilepath ytempFilepathR. El siguiente paso es importar estos dos archivos y aquí es donde me encuentro con un problema.

Parte 2: Importar los archivos

El problema con el que me encuentro es el siguiente: Implementé la biblioteca LibAIFF para importar los archivos. El problema es que si ejecuto el programa, digamos N veces, luego en algunas de las ejecuciones, el primer archivo se importa pero no el segundo, en otras ejecuciones se importa el segundo pero no el primero (tenga en cuenta que si el primero no Si se importa, el programa se detiene).Antes de explicar el error, sepa que no hay ningún problema con los archivos AIFF, por el bien de este problema, puede suponer que son idénticos y que incluso sus rutas absolutas y nombres de archivo son idénticos, excepto que uno tiene un sufijoA.aiff y el otroB.aiff. Estas rutas de archivo se almacenan como cadenas en variables idénticamente definidas (tempFilepath ytempFilepathR)

Aquí está el resto de la parte necesaria de mi código continuado desde arriba

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.
}

La ruptura siempre ocurre dentro de la función import_sweeps () (a veces para el primer AIFF y a veces para el segundo). La función se muestra a continuación.

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

Dentro de import_sweeps () arriba, el archivo AIFF SIEMPRE se lee con éxito llamando a la funciónAIFF_ReadSamples32Bit(fileref, samples, nSamplePts);. Por lo tanto, el valor temporal nunca es -1. Cada vez que ocurre un error (como se describe arriba y daré el mensaje de error real a continuación), SIEMPRE ocurre cuando intenta llamarAIFF_CloseFile(fileref);.

A continuación se muestran las funciones.AIFF_ReadSamples32Bit yAIFF_CloseFile como se define en la biblioteca 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;
}

y

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

La ruptura ocurre a lasAIFF_ReadClose(ref); CADA VEZ. Entonces también he mostrado esta función a continuación.

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

La ruptura siempre ocurre como se muestra arriba. El siguiente es elmensaje de error: (25693,0x7fff7db87310) malloc:* error para el objeto 0x4000000000000000: el puntero que se está liberando no se asignó * establecer un punto de interrupción en malloc_error_break para depurar

Entonces, básicamente, se produce el error anteriorimpredecible. Cuando no ocurre, mi código funciona perfectamente.Cualquier ayuda sobre cómo podría resolver este problema es muy apreciada.

SI ALGUIEN ESTÁ DISPUESTO A DESCARGAR LA BIBLIOTECA LIBAIFF PARA INVESTIGAR MÁS Y AYUDARME, el enlace a la biblioteca es:http://aifftools.sourceforge.net/libaiff/.

¡Gracias de antemano por cualquier sugerencia!

Respuestas a la pregunta(1)

Su respuesta a la pregunta