2014-03-04 57 views
0

我不擅長C編程,所以請原諒,如果這不是一個強有力的問題。在下面的代碼中,我只能在獲得nsamplepts的值後分配內存到samplesVec,但我需要將矢量samplesVec返回到main以供進一步使用(尚未編碼)。不過,我發現了以下錯誤:被釋放的指針未被分配,中止陷阱:6

錯誤在終端窗口: ImportSweeps(3497,0x7fff7b129310)的malloc:*錯誤對象0x7fdaa0c03af8:指針被釋放沒有被分配 *設置一個斷點malloc_error_break調試 中止陷阱:6

我正在使用Mac OS X Mavericks和gcc編譯器。謝謝你的幫助。

* EDITED !!!在評論者的有價值的輸入之後,以下代表原始問題的解決方案(不再可用)*

以下代碼修改似乎解決了我原來的問題。感謝大家的寶貴意見!

/* Header Files */ 
#define LIBAIFF_NOCOMPAT 1 // do not use LibAiff 2 API compatibility 
#include <libaiff/libaiff.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <dirent.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <math.h> 

/* Function Declarations */ 
void FileSearch(char*, char*, char*, char*, char*); 
int32_t *ImportSweeps(char*); 

/* Main */ 
int main() 
{ 
char flag1[2] = "N"; 
char binname[20] = "bin1"; // dummy assignment 
char buildfilename[40] = "SweepR"; 
char skeletonpath[100] = "/Users/.../Folder name/"; 
int k, len; 

/* Find the sweep to be imported in the directory given by filepath */ 
FileSearch(skeletonpath, binname, buildfilename, skeletonpath, flag1); 
if (strcmp(flag1,"Y")) { 
    printf("No file found. End of program.\n"); 
} else { 
    len = (int) strlen(skeletonpath); 
    char *filepath = malloc(len); 
    for (k = 0; k < len; k++) { 
     filepath[k] = skeletonpath[k]; 
    } 
    printf("File found! Filepath: %s\n", filepath); 
    // Proceed to import sweep 
    int32_t *sweepRfile = ImportSweeps(filepath); 
    if (sweepRfile) { 
     printf("Success!\n"); 
     // Do other things with sweepRfile 
     free(sweepRfile); 
    } 
    free(filepath); 
} 
return 0; 
} 

/* Sub-Routines */ 
void FileSearch(char *dir, char *binname, char *buildfilename, char* filepath, char* flag1) 
{ 
DIR *dp; 
struct dirent *entry; 
struct stat statbuf; 
if((dp = opendir(dir)) == NULL) { 
    fprintf(stderr,"Cannot open directory: %s\n", dir); 
    return; 
} 
chdir(dir); 
while((entry = readdir(dp)) != NULL) { 
    lstat(entry->d_name, &statbuf); 
    if(S_ISDIR(statbuf.st_mode)) { 
     /* Found a directory, but ignore . and .. */ 
     if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0) 
      continue; 
     strcpy(binname,entry->d_name); 
     strcpy(buildfilename,"SweepR"); 
     /* Recurse at a new indent level */ 
     FileSearch(entry->d_name, binname, buildfilename, filepath, flag1); 
    } 
    else { 
     sprintf(buildfilename, "%s%s.aiff", buildfilename, binname); 
     if (strcmp(entry->d_name,buildfilename)) { 
      strcpy(buildfilename,"SweepR"); 
     } else { 
      sprintf(filepath, "%s%s/%s", filepath, binname, buildfilename); 
      strcpy(flag1,"Y"); 
      break; 
     } 
    } 
} 
chdir(".."); 
closedir(dp); 
} 


int32_t *ImportSweeps(char *filepath) 
{ 
char *filepathread = filepath; 

/* Initialize files for importing */ 
AIFF_Ref fileref; 

/* Intialize files for getting information about AIFF file */ 
uint64_t nSamples; 
int32_t *samples = NULL; 
int32_t *samplesVec = NULL; 
int channels, bitsPerSample, segmentSize, ghost, nsamplepts; 
double samplingRate; 

/* Import Routine */ 
fileref = AIFF_OpenFile(filepathread, F_RDONLY) ; 
if(fileref) 
{ 
    // File opened successfully. Proceed. 
    ghost = AIFF_GetAudioFormat(fileref, &nSamples, &channels, &samplingRate, &bitsPerSample, &segmentSize); 
    if (ghost < 1) 
    { 
     printf("Error getting audio format.\n"); 
     AIFF_CloseFile(fileref); return (int32_t) 0; 
    } 
    nsamplepts = ((int) nSamples)*channels; 
    samples = malloc(nsamplepts * sizeof(int32_t)); 
    samplesVec = malloc(nsamplepts * sizeof(int32_t)); 
    ghost = AIFF_ReadSamples32Bit(fileref, samples, nsamplepts); 
    if (ghost) { 
     for (int k = 0; k < nsamplepts; k++) { 
      samplesVec[k] = *(samples+k); 
     } 
    } 
    free(samples); 
    AIFF_CloseFile(fileref); 
} 
return samplesVec; 
} 
+0

'ImportSweeps'返回什麼?我只問,因爲這個區域的代碼看起來像是因爲sizeof(sweepRfile)/ sizeof(int32_t)'不符合你的想法...... – John3136

+0

@ John3136 ImportSweeps應該返回一個名爲samplesVec的大型矢量,它包含int32_t類型的數據(在我正在使用的libaiff庫中定義)。 – Rahul

+0

沒問題,但打印出來的長度是錯誤的(sizeof pointer/sizeof int)大概是1. – John3136

回答

1

所以......據我可以看到... ... :-)

samplesVecImportSweeps返回值沒有初始化,如果fileref是假的。如果samplesVec沒有明確初始化,自動(==本地)變量對其值沒有保證 - 換句話說,samplesVec可以攜帶任何地址。如果samplesVec在運氣上不是NULL(在另一方面可能經常是這種情況),那麼您嘗試使用free未分配的內存垃圾,或者在其他地方分配了一個非常不幸的運氣。

如果我和我的猜測正確,你可以容易解決這個問題:

int32_t *samples; 
int32_t *samplesVec = NULL; 

這是一個好主意,反正到一些有意義的錯誤或虛假值儘快初始化任何變量,如果你不要在下一行使用它。由於指針是可怕的野獸,我總是NULL他們,如果我不初始化他們在聲明有用的價值。

編輯:一些可讀的近似英語的小改動。 :-)

+0

'samplesVec'被初始化。我通過打印它的第二個值來檢查它。我還在'free(samples)'之後給出了一個'printf(「Test \ n」);'命令並執行了這個命令。但它看起來像'samplesVec'沒有被返回到'main',因爲在'int32_t * sweepRfile = ImportSweeps(filepath)'行之後寫入的'printf(「Test \ n」);'命令不會被執行。 – Rahul

+0

由於使用正確的'AIFF_OpenFile',所以在代碼中看不到任何其他錯誤。當然,你的一個庫函數總是可能使用malloc()/ free(),並且是有問題的,或者有其他未知的輸入。 –

+0

我已經確定了一些東西......也許你可以幫助我找出問題......在主函數中,如果我繞過函數FileSearch(filepath,binname,buildfilename,filepath,flag1);',更改'char filepath [ 100] =「/ Users /.../ Foldername /」;'以包含FileSearch通常找到的文件的地址(我相信這是正確的 - 它們具有相同的長度)並設置char flag1 [2] =「Y」;'到函數'int32_t * ImportSweeps(char * filepath)',那麼我需要包含'AIFF_CloseFile(fileref);'。只要FileSearch功能被繞過,一切似乎都能正常工作。 – Rahul

0

如果AIFF_OpenFile失敗,則ImportSweeps將返回未定義的值,因爲SamplesVec未初始化。如果該值不是NULL,main將嘗試釋放它。您可以初始化samplesVec = NULL,或者你可以重新組織代碼

fileref = AIFF_OpenFile(filepathread, F_RDONLY) ; 
if(!fileref) { 
{ 
    // print error message here 
    return NULL; 
} 
// File opened successfully. Proceed. 
... 

有些人誰都會堅持一個functon應該只有一個出口 - 他們是很差知情和清濁有故障的教條從傳世其他同樣不知情和教條的人。上面的錯誤和返回檢查被稱爲警衛條款。每次測試成功時縮進的樣式都會產生箭頭反模式,該模式更難以閱讀,難以修改,並且更容易出錯。參見http://blog.codinghorror.com/flattening-arrow-code/http://c2.com/cgi/wiki?ArrowAntiPattern進行一些討論。

+0

我試過你的方法無濟於事。迴應我以前的評論:'samplesVec'被初始化。我通過打印它的第二個值來檢查它。我還在'free(samples)'之後給出了一個'printf(「Test \ n」);'命令並執行了這個命令。但它看起來像'samplesVec'沒有被返回到'main',因爲在'int32_t * sweepRfile = ImportSweeps(filepath)'行之後寫入的'printf(「Test \ n」);'命令不會被執行。 – Rahul

+0

恩,samplesVec是**未初始化;看到,就在那裏 - 'int32_t * samples,* samplesVec;'沒有初始化。它獲取*設置*,但只有當'fileref'不是NULL時。至於printf語句 - printf被緩衝,如果程序崩潰,你將看不到輸出。切勿將其用於調試輸出 - 請改用fprintf(stderr,...)。 –

+0

感謝您的意見。我剛剛在程序中初始化'samplesVec'(根據Mark A.的建議,爲NULL)。所以我已經注意到了,但最初的問題仍然存在。 – Rahul

相關問題