2014-12-19 4 views
0

Я передаю указатель на структуру typedef для функции, которая, как предполагается, создает структуру typedef для использования. Структура уже выведена до того, как она будет передана функции. При доступе к структуре внутри функции я получаю EXC_BAD_ACCESS. Вещь, которую я не понимаю, значение структуры typedef, называемой пулом, действительна в предыдущей функции, но как только она передается, она недействительна. Это видно ниже. Во время исследования проблемы я видел похожие проблемы, но это связано с передачей копии переменной функции вместо указателя или потому, что переменная была локальной переменной, и она вышла из области действия, когда функция завершилась. Я не считаю, что это проблемы, потому что функция, объявленная и malloced пул еще не вышел, и я передаю указатель, чтобы пул не копия пула. Итак, как же пул становится NULL после передачи его initNamePool?Передача указателя на функцию corrupts pointer

Backtrace, здесь вы можете увидеть, что бассейн был действительно в "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 

Определение данных-> бассейн-> 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, содержащую пул. Оба получают malloced в "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; 
    } 

    ... 
} 

После того, как мы таНос данные и данных-> пул и мы передаем данные в "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

+0

Я сделал malloc pool-> nPool, он просто ушел из вопроса об аварии, он сразу же после data-> pool в initFuzzData. – 2trill2spill

+1

Попробуйте распечатать адреса переменных после выделения и непосредственно перед и после (или внутри функции) вызова функции. Возможно, это прояснит ситуацию. – NikolayKondratyev

ответ

1

Я нашел его, напечатав адреса, у меня был дважды сложенный пул в initFuzzData. - 2trill2spill

Смежные вопросы