int err = pthread_create( &p, NULL, pro, (void*)1);
每次运行程序时,我都会遇到段错误,我读到它并了解到线程正在尝试读取而操作系统正在阻止它。我查看了代码以找到错误,但我遇到了困难,因为我没有与 C 配合良好的调试器。
有人可以帮我解决这个问题吗?
最佳答案
使用 GDB(你应该使用它)你可以在程序崩溃时获得一些有用的信息。
首先使用“-g”构建程序
gcc file.c -lpthread -g
然后在 gdb 中运行它。
你会看到这个:
Thread 2 "a.out" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff781e700 (LWP 8082)]
0x0000000000400b94 in produce (arg=0x1) at test.c:84
84 int id = *(int*) arg;
从那里很明显,有罪的路线是:
int id = *(int*) arg;
让我们看看您在这里到底做了什么:
您想要获取该参数以便可以使用它。 这是正确的...
但是看看如何将参数传递给函数:
int err = pthread_create( &producer_thread1, NULL, produce, (void*)1);
您正在获取值“1”,并将其转换为 void *。为什么不......即使除了某些特殊情况之外你永远不会真正想要这样做......但在你的具体情况下它绝对不是你想要的,为什么?
因为在 Produce 函数内部,您认为它是指向 int 的指针,但事实并非如此!它是一个转换为 void * 的数字 (1),因此在您的系统上,它可能已被转换为 64 位上写入的值 (1),但它仍然是 1。因此,当您尝试取消引用它时,您会得到一个段错误。
尝试将这些值声明为变量并将它们的地址传递给 pthread_create 函数(全部)
编辑
int err = pthread_create( &producer_thread1, NULL, produce, (void*)1);
会变成:
int err = pthread_create( &producer_thread1, NULL, produce, (void*)&one);
其中变量“one”可以是这样的全局变量:
int one = 1;
但它也可能是一个分配的 int 或任何具有您选择的地址的 int.. 只是不要传递一个不是的值,并且像它一样处理它。
希望这能有所帮助。
关于c - 分段默认(核心转储),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40069538/