从 void ptr 取消引用整数时的 SegFault
SegFault when dereferencing integer from void ptr
这是我的代码,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 = rt->values[i];
分配给 ptr
的地址是正确的,因为每当我复制从 gdb 打印的地址并执行 print (address) 时,它会打印出正确值为 625。
当地址正确指向整数时,为什么我会收到段错误?
编辑: 我已经按照其他用户的要求用我的整个 tuple.c 文件替换了问题的当前代码内容,如上所示。
如果 *ptr
是 625,那么 *valPtr
正在取消引用地址 625。
如果您在调试器中 运行 this,请在取消引用时查看 valPtr 的值。
您的所有 malloc 都在泄漏内存,因为您在下一行覆盖了 malloc return:
void* ptr = malloc(sizeof(rt->values[i]));
ptr = rt->values[i]; // You've now lost the pointer to malloced memory.
您似乎想要 *ptr = ...
之类的东西来将某些东西放入您新创建的块中。在 intPtr
的情况下,您将其值设置为一个 int,然后再次尝试将其用作指针。由于它不太可能是有效地址,因此您会遇到段错误。
这是我的代码,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 = rt->values[i];
分配给 ptr
的地址是正确的,因为每当我复制从 gdb 打印的地址并执行 print (address) 时,它会打印出正确值为 625。
当地址正确指向整数时,为什么我会收到段错误?
编辑: 我已经按照其他用户的要求用我的整个 tuple.c 文件替换了问题的当前代码内容,如上所示。
如果 *ptr
是 625,那么 *valPtr
正在取消引用地址 625。
如果您在调试器中 运行 this,请在取消引用时查看 valPtr 的值。
您的所有 malloc 都在泄漏内存,因为您在下一行覆盖了 malloc return:
void* ptr = malloc(sizeof(rt->values[i]));
ptr = rt->values[i]; // You've now lost the pointer to malloced memory.
您似乎想要 *ptr = ...
之类的东西来将某些东西放入您新创建的块中。在 intPtr
的情况下,您将其值设置为一个 int,然后再次尝试将其用作指针。由于它不太可能是有效地址,因此您会遇到段错误。