2014-12-19 172 views
0

我將一個指向typedef結構體的指針傳遞給一個函數,該函數假設設置了typedef結構體以供使用。在傳遞給函數之前,該結構已經被綁定了。在訪問函數中的結構體時,我會收到EXC_BAD_ACCESS。我不明白的是,名爲pool的typedef結構的值在前一個函數中是有效的,但一旦它被傳遞,它就無效了。這可以在下面的回溯中看到。在研究這個問題的時候,我看到了類似的問題,但是這些是由於將變量的副本傳遞給函數而不是指針,或者因爲變量是局部變量,並且在函數退出時它超出了範圍。我不相信這些是問題,因爲聲明和mableced池的函數還沒有退出,並且我正在傳遞一個指向池但不是池副本的指針。那麼在將它傳遞給initNamePool之後,pool如何變爲NULL?將指針傳遞給函數損壞指針

回溯,在這裏你可以看到,池在 「initResourcePool」 和 「initPools」 有效的,但不是 「initNamePool」

(lldb) thread backtrace 
* thread #1: tid = 0x53998, 0x000000010000325b sysfuzz`initNamePool(pool=0x0000000000000000) + 27 at namePool.c:201, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4020) 
    * frame #0: 0x000000010000325b sysfuzz`initNamePool(pool=0x0000000000000000) + 27 at namePool.c:201 
    frame #1: 0x0000000100002cf5 sysfuzz`initPools(pool=0x00000001003eafe0) + 37 at pool.c:51 
    frame #2: 0x0000000100002c80 sysfuzz`initResourcePool(pool=0x00000001003eafe0) + 48 at pool.c:87 
    frame #3: 0x0000000100001830 sysfuzz`initSysFuzz(data=0x00000001003d4fd0) + 48 at interactor.c:19 
    frame #4: 0x00000001000017ba sysfuzz`initAndRunSysFuzz + 58 at interactor.c:103 
    frame #5: 0x0000000100001599 sysfuzz`main + 25 at start.c:12 
    frame #6: 0x00007fff956395c9 libdyld.dylib`start + 1 
    frame #7: 0x00007fff956395c9 libdyld.dylib`start + 1 

的定義數據 - > pool-> nPool和getDirName

static int getDirName(char **dir, namePool *pool) 
{ 
    poolArgs *args; 

    args = (poolArgs *) malloc(sizeof(poolArgs)); 
    if(args == NULL) 
    { 
     return -1; 
    } 

    launchSynch(pool->serialQueue, gdn, &args); 

    dir = args->dir; 

    free(args); 

    return 0; 
} 

typedef struct namePool namePool; 

struct namePool 
{ 
    char *fileNameIndex[1025]; 
    char *dirNameIndex[1025]; 
    queue serialQueue; 

    int (*getFileName)(char **, namePool *); 
    int (*getDirName)(char **, namePool *); 
    int (*fillPool)(namePool *); 
    int (*drainPool)(namePool *); 
    bool isPoolDrained; 
}; 

這裏我們聲明的數據是一個typedef結構,它擁有池。兩者都在「initFuzzData」中進行匹配。

int initAndRunSysFuzz() 
{ 
    /* Declarations. */ 
    int rtrn; 
    fuzzData *data; 

    data = initFuzzData(); 
    if(data == NULL) 
    { 
     return -1; 
    } 

    rtrn = initSysFuzz(data); 
    if(rtrn < 0) 
    { 
     cleanUpFuzzData(data); 
     return -1; 
    } 

    ... 
} 

fuzzData *initFuzzData() 
{ 
    fuzzData *data; 

    data = (fuzzData *) malloc(sizeof(fuzzData)); 
    if(data == NULL) 
    { 
     return NULL; 
    } 

    data->pool = (resourcePool *) malloc(sizeof(resourcePool)); 
    if(data->pool == NULL) 
    { 
     return NULL; 
    } 

    data->pool->nPool = (namePool *) malloc(sizeof(namePool)); 
    if(data->pool->nPool == NULL) 
    { 
     return NULL; 
    } 

    ... 
} 

後,我們的malloc數據和數據>游泳池,我們通過 「initSysFuzz」

static int initSysFuzz(fuzzData *data) 
{ 

    int rtrn; 

    rtrn = initResourcePool(data->pool); 
    if(rtrn < 0) 
    { 
     return -1; 
    } 

    ... 
} 

「initSysFuzz」 呼叫 「initResourcePool」

int initResourcePool(resourcePool *pool) 
{ 

    int rtrn; 

    rtrn = initPools(pool); 
    if(rtrn < 0) 
    { 
     printf("Can't Init Pools\n"); 
     return -1; 
    } 
    ... 
} 

數據依次調用「 initPools」

static int initPools(resourcePool *pool) 
{ 
    int rtrn; 

    rtrn = initNamePool(pool->nPool); 
    if(rtrn < 0) 
    { 
     printf("Can't init name pool\n"); 
     return -1; 
    } 

    .... 
} 

這裏是崩潰的地方,在「initNamePool」,pool-> getDirName =&getDirName的第一行; 。

int initNamePool(namePool *pool) 
{ 
    pool->getDirName = &getDirName; 

... 

} 
+3

您正在將'pool-> nPool'傳遞給'initNamePool',但您從未爲該指針分配任何內容。告訴我們你的代碼在哪裏'pool-> nPool = ....'完成了,因爲我沒有看到它。 – WhozCraig 2014-12-19 04:16:35

+0

我做了malloc pool-> nPool它只是在事故問題中不存在,它在initFuzzData中的數據 - >池後馬上連接。 – 2trill2spill 2014-12-19 04:24:23

+1

嘗試打印分配後的變量地址,以及函數調用之前和之後(或函數內部)。也許這會澄清情況。 – NikolayKondratyev 2014-12-19 04:54:32

回答

1

我通過打印地址發現它,我在initFuzzData中有兩次mableced池。 - 2trill2spill