似乎大多数答案从未真正尝试过运行您的代码。这是一个非常简约的程序,确实显示了您的问题:
#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== 由 0x80484A1: main (srand_ko.c:10) ==22907== 地址 0x0 是未堆叠、malloc 或(最近)释放
现在查看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. */
};
显然,如果您使用 分配,所有这些指针都将为 NULL calloc()
,并且srandom_r
并不真正喜欢那样。您可以帮助它手动分配状态值数组并将其分配给random_data
使用initstate_r
. 因为initstate_r
已经需要 a 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;
}