Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么srand(time(NULL))在main上给我分段错误?_C_Random_Time_Srand_Ucontext - Fatal编程技术网

C 为什么srand(time(NULL))在main上给我分段错误?

C 为什么srand(time(NULL))在main上给我分段错误?,c,random,time,srand,ucontext,C,Random,Time,Srand,Ucontext,这里需要帮助 我想了解这段代码中发生了什么 我正在尝试生成随机数,作为tickets到TCP\u tstruct,该结构是在ccreate函数中创建的 问题是,每次我在没有srand(time(NULL))的情况下执行此代码时,它都会反复返回相同的“随机”数序列,例如: TID: 0 | TICKET : 103 TID: 1 | TICKET : 198 所以我把它和时间一起播种,以产生真正的随机数 当我将种子放入newTicket函数中时,它在每次执行中都会带来不同的数字,但每个线程的数字

这里需要帮助

我想了解这段代码中发生了什么

我正在尝试生成随机数,作为
tickets
TCP\u t
struct,该结构是在
ccreate
函数中创建的

问题是,每次我在没有srand(time(NULL))的情况下执行此代码时,它都会反复返回相同的“随机”数序列,例如:

TID: 0 | TICKET : 103
TID: 1 | TICKET : 198
所以我把它和时间一起播种,以产生真正的随机数

当我将种子放入
newTicket
函数中时,它在每次执行中都会带来不同的数字,但每个线程的数字都相同。以下是一个输出示例:

执行1:

TID: 0 | TICKET : 148
TID: 1 | TICKET : 148
执行2:

TID: 0 | TICKET : 96
TID: 1 | TICKET : 96
因此,经过一些研究,我发现我不应该每次调用
rand
时都给它播种子,而应该在程序开始时只播一次。现在,在将种子放入
main
函数后,它给了我分段错误,我不知道为什么

这可能是个愚蠢的问题,但我真的想知道发生了什么

不知怎么的,种子有什么问题吗? 我错过什么了吗? 我应该用另一种方法生成随机数吗

#include <ucontext.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define MAX_TICKET 255
#define STACK_SIZE 32000

typedef struct s_TCB {
  int threadId;
  int ticket;
  ucontext_t context;
} TCB_t;

void test();
int newTicket();
int newThreadId();
int ccreate (void* (*start)(void*), void *arg);
int threadId = 0;

int main(){
  srand(time(NULL)); //<<<============== HERE = SEGMENTATION FAULT
  ccreate((void*)&test, 0);
  ccreate((void*)&test, 0);
}

int ccreate (void* (*start)(void*), void *arg){
    if(start == NULL) return -1;

    ucontext_t threadContext;
    getcontext(&threadContext);
    makecontext(&threadContext, (void*)start, 0);
    threadContext.uc_stack.ss_sp = malloc(STACK_SIZE);
    threadContext.uc_stack.ss_size = STACK_SIZE;

    TCB_t * newThread = malloc(sizeof(TCB_t));
    if (newThread == NULL) return -1;

    int threadThreadId = newThreadId();
    newThread->threadId = threadThreadId;
    newThread->ticket = newTicket();

    printf("TID: %d | TICKET : %d\n", newThread->threadId, newThread->ticket);

    return threadThreadId;
}

int newThreadId(){
  int newThreadId = threadId;
  threadId++;
  return newThreadId;
}

int newTicket(){
  //srand(time(NULL)); //<<<============== HERE = IT PARTIALLY WORKS
  return (rand() % (MAX_TICKET+1));
}

void test(){
  printf("this is a test function");
}
#包括
#包括
#包括
#包括
#定义最大票证255
#定义堆栈大小32000
类型定义结构s_TCB{
int-threadId;
国际机票;
ucontext\u t context;
}TCB_t;
无效试验();
int newTicket();
int newThreadId();
int ccreate(void*(*start)(void*),void*arg);
int-threadId=0;
int main(){
srand(time(NULL));//threadId,newThread->ticket);
返回threadid;
}
int newThreadId(){
int newThreadId=threadId;
threadId++;
返回newThreadId;
}
int newTicket(){

//srand(time(NULL));//问题不在于
srand(time(NULL))
,而在于
makecontext

您可以通过sanatizer运行代码以确认:

gcc-6 -fsanitize=undefined -fsanitize=address -fsanitize=leak -fsanitize-recover=all -fuse-ld=gold -o main main.c
./main 
ASAN:DEADLYSIGNAL
=================================================================
==8841==ERROR: AddressSanitizer: SEGV on unknown address 0x7fc342ade618 (pc 0x7fc340aad235 bp 0x7ffd1b945950 sp 0x7ffd1b9454f8 T0)
    #0 0x7fc340aad234 in makecontext (/lib/x86_64-linux-gnu/libc.so.6+0x47234)
    #1 0x400d2f in ccreate (/home/malko/Desktop/main+0x400d2f)
    #2 0x400c19 in main (/home/malko/Desktop/main+0x400c19)
    #3 0x7fc340a87f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #4 0x400b28  (/home/malko/Desktop/main+0x400b28)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0x47234) in makecontext
==8841==ABORTING
您可以通过在创建上下文之前设置堆栈大小来解决此问题:

char stack[20000];
threadContext.uc_stack.ss_sp = stack;
threadContext.uc_stack.ss_size = sizeof(stack);
makecontext(&threadContext, (void*)start, 0);


不相关,但请确保您还释放了示例代码中的malloc'd内存。

只是OOC,为什么您要使用相同的参数连续调用
ccreate
两次?您是否100%确定seg错误实际上位于
种子
s?
ccreate((void*)&test 0)的行上
没有理由在这里强制转换。我没有
ucontext.h
所以我不得不删除所有的ccreate,但是我没有得到一个seg保险库。你确定srand是问题所在吗?你能举一个较小的例子吗?()更有可能是
ccreate((void*)&test,0);
导致了segfault,但它被误传为在srand行上