我在我的智慧结束。 这个微不足道的代码给了我Segfault,可能是什么错误?
struct random_data *qq; qq = calloc(50, sizeof(struct random_data)); srandom_r(time(NULL), qq);
现在,如果我改变它,它的作品:
struct random_data qq; srandom_r(time(NULL), &qq);
我一定是一个白痴,但我无法把握。 请帮忙。
更新:calloc返回一个有效的指针
(uint64_t) 1aa5010
不过,&qq代表指针
(uint64_t) 7fffbb428090
这就是区别,但是为什么srandom_r执行失败还不清楚。 我尝试在Linux 2.6.32-44-server#98-Ubuntu
它似乎像大多数答案从来没有真的试图运行你的代码。 这是一个非常简约的程序,确实展示你的问题:
#include <stdlib.h> #include <stdio.h> #include <time.h> int main() { int seed = time(NULL); struct random_data *qq = NULL; qq = calloc(1, sizeof(struct random_data)); if(qq) { srandom_r(seed, qq); /* segfault! */ } else { printf("failed to allocate `qq`\n"); } return 0; }
valgrind没有显示出非法的内存访问:
== 22907 ==无效的写入大小4 == 22907 ==在0x409CE8D:srandom_r(random_r.c:182)== 22907 == by 0x80484A1:main(srand_ko.c:10)== 22907 ==地址0x0是不是stack'd,malloc'd或(最近)free'd
现在,在查看random_data
结构时,您会发现它包含一个指向状态缓冲区的指针:
struct random_data { int32_t *fptr; /* Front pointer. */ int32_t *rptr; /* Rear pointer. */ int32_t *state; /* Array of state values. */ int rand_type; /* Type of random number generator. */ int rand_deg; /* Degree of random number generator. */ int rand_sep; /* Distance between front and rear. */ int32_t *end_ptr; /* Pointer behind state table. */ };
显然,如果使用calloc()
分配,那么所有这些指针都将为NULL,而srandom_r
并不真的如此。 你可以帮助它手动分配一个状态值的数组,并使用initstate_r
将其分配给random_data
结构体。 因为initstate_r
已经接受了一个seed
,所以你不需要再调用srandom_r
(但是如果你愿意,你可以):
#include <stdlib.h> #include <stdio.h> #include <time.h> #define STATESIZE 64 int main() { int seed = time(NULL); char*buf = (char*)calloc(STATESIZE, sizeof(char)); struct random_data *qq = NULL; qq = calloc(1, sizeof(struct random_data)); initstate_r(seed, buf, STATESIZE, qq); /* generate some random numbers */ /* ... */ srandom_r(seed, qq); /* generate the same random numbers again */ /* ... */ /* cleanup */ free(buf); free(qq); return 0; }
您可能会喜欢ot添加一个测试是否calloc()
成功,因为传递NULL
最有可能挑起分割侵犯。
#include <stdlib.h> ... struct random_data * qq = calloc(50, sizeof(*qq)); if (NULL == qq) perror("malloc() failed"); else srandom_r(time(NULL), qq);