从void ptr取消引用整数时的SegFault

时间:2016-06-26 23:51:59

标签: c pointers segmentation-fault dereference

这是我的代码,Tuple.c,它在行上生成了一个SegFault,并带有注释说:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

void dbwait();

typedef struct STuple {
    int tSize;
    void** values;
} Tuple;

Tuple* CreateTuple(int n_args, ...) {
    va_list varlist;
    va_start(varlist, n_args);

    int varsSize;
    void** vars = (void**)malloc(n_args * sizeof(void*));

    for (int i = 0; i < n_args; i++) {
        void* arg = va_arg(varlist, void*);
        varsSize += sizeof(arg);
        vars[i] = arg;
        printf("Arg ptr = %p\n", arg);
    }

    // Size of all of the arguments + size of an int value (varsSize) since Tuple has an array of void* and a single int.
    Tuple* t = (Tuple*)malloc(varsSize + sizeof(varsSize));

    t->values = vars;
    t->tSize = n_args;

    va_end(varlist);

    return t;
}

void FreeTuple(Tuple* t) {
    printf("Freeing tuple at %p\n", (void*)t);
    free(t->values);
    free(t);
}

int main(int argc, char** argv) {
    Tuple* rt = CreateTuple(3, 625, 173, 50);

    int length = rt->tSize;

    printf("%i\n", length); // Prints 3, as defined in the call to CreateTuple
    dbwait();

    for (int i = 0; i < length; i++) {

        printf("index = %i: ", i);
        dbwait();

        void* ptr = rt->values[i];
        printf("At ptr %p, ", ptr); dbwait();

        int value = *((int*)ptr); // SegFault Occurs here!
        printf("with value = %d\n", value);
        dbwait();
    }

    dbwait();

    FreeTuple(rt);

    return 0;
}

void dbwait() {
    char* stop = (char*)malloc(sizeof(char));
    scanf("%c", stop);
    free(stop);
}

我知道在ptr分配给ptr = rt->values[i];的地址是正确的,因为每当我将该地址复制为从gdb打印并执行print(地址)时,它会打印出正确的值625。

为什么我在地址正确指向整数时获得SegFault?

编辑:我已根据其他用户的要求,将我的问题的当前代码内容替换为我的整个tuple.c文件,如上所示。

2 个答案:

答案 0 :(得分:2)

如果*ptr为625,则*valPtr将取消引用地址625.

如果您在调试器中运行它,请在解除引用时查看valPtr的值。

答案 1 :(得分:0)

你的所有malloc都在泄漏内存,因为你在下一行写过mallocs返回:

void* ptr = malloc(sizeof(rt->values[i]));
ptr = rt->values[i]; // You've now lost the pointer to malloced memory.

看起来你想要像*ptr = ...这样的东西把东西放到新创建的块中。在intPtr的情况下,将其值设置为int,然后再次尝试将其用作指针。由于它不太可能是有效的地址,因此会出现段错误。