将指针传递给函数会破坏指针

时间:2014-12-19 04:12:49

标签: c pointers struct

我将一个指向typedef结构的指针传递给一个函数,该函数假设设置了typedef结构以供使用。在将结构传递给函数之前,该结构已经被malloced。在访问函数内的结构时,我收到EXC_BAD_ACCESS。我不明白的是,名为pool的typedef结构的值在前一个函数中是有效的,但是一旦它通过它就无效。这可以在下面的回溯中看到。在研究问题的同时,我看到了类似的问题,但那些是由于将变量的副本传递给函数而不是指针,或者因为变量是局部变量,并且当函数退出时它超出了范围。我不相信这些是问题,因为声明和malloced池的函数还没有退出,我传给指向池的指针而不是池的副本。那么在将它传递给initNamePool之后,如何将池变为NULL?

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

数据的定义 - > 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"。

中进行了malloced
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数据和数据 - &gt;池之后,我们将数据传递给&#34; initSysFuzz&#34;

static int initSysFuzz(fuzzData *data)
{

    int rtrn;

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

    ...
}

&#34; initSysFuzz&#34;调用&#34; initResourcePool&#34;

int initResourcePool(resourcePool *pool)
{

    int rtrn;

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

反过来调用&#34; initPools&#34;

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

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

    ....
}

这是崩溃的地方,在第一行&#34; initNamePool&#34;,pool-&gt; getDirName =&amp; getDirName;

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

...

}

1 个答案:

答案 0 :(得分:1)

我通过打印地址找到它,我在initFuzzData中有两次malloced池。 - 2trill2spill