将睡眠与 Pthreads 一起使用时在 C 中出现分段错误
Getting Segmentation Fault in C when using sleep with Pthreads
我正在使用 PThreads 在 C 语言中创建一个线程,它在无限循环中执行一个 运行 函数,并每秒在控制台中打印一些随机 json 字符串。一开始他打印函数 simulateLED 的结果没有问题,但在休眠 1 秒后,我会得到一个 Segmentation Fault (Core dumped)。如果我删除睡眠,我就不会得到它并且程序运行正常。为什么我在休眠时会出现分段错误以及如何修复它?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char *simulateLED() {
int temp;
int luftf;
char* jsonString;
time_t t;
srand((unsigned) time(&t));
int x=-10, y=50;
temp=(rand()%((y+1)-x))+x;
x=2, y=30;
luftf=(rand()%((y+1)-x))+x;
printf("%d %d\n", temp, luftf);
fflush(stdout);
sprintf(jsonString, "{\n\"TEMP\": %d,\n\"HUMI\": %d\n}", temp, luftf);
return jsonString;
}
void *simAndSendThread(void *param) {
while(1) {
printf("%s", simulateLED());
sleep(1);
}
}
int main(int argc, char *argv[]) {
pthread_t thread;
if(pthread_create(&thread, NULL, simAndSendThread, NULL)) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
if(pthread_join(thread, NULL)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
pthread_exit(NULL);
return 0;
}
您尚未为 jsonString
分配内存,但仍在尝试执行 sprintf
以及在 return print
之后
试试这个
char* jsonString;
jsonString = malloc( 1024 );
完成后别忘了 free
,您使用的是 while(1)
,如果您不使用 free
,您很有可能会点击 内存不足 错误很快。
如果你 enable full warnings
你应该收到一个 warning message for uninitialized variable
最终会避免所有的崩溃。
正如@DavidSchwartz 所指出的,Segmentation fault (core dumped)
错误的原因与当前未初始化的 jsonString
指针有关(即,未 指向 到任何东西)。因此,sprintf
正在写入一个随机位置,有时可能会或可能不会。
为了修复它,可以在声明的时候静态地把space赋值给jsonString
变量,比如:
...
char jsonString[256];
...
这意味着您可以拥有最多 255
个字符的字符串(1
个额外字符保留给 [=18=]
)。或者,您可以使用 malloc
:
动态分配 space
...
char *jsonString = (char *)malloc(sizeof(char) * 256);
// Your code here
free(jsonString);
...
在这种情况下,你必须记得在你的函数结束时使用free
释放分配,否则你会泄漏内存。如果您还没有了解动态内存,请参阅 When and why to use malloc?。
P.S.: 如果你在Linux,我强烈建议你在出现内存相关错误时使用valgrind
。这个工具很可能会提示你在哪里犯了错误。查看 Valgrind Quick Start Guide 了解更多信息。
我正在使用 PThreads 在 C 语言中创建一个线程,它在无限循环中执行一个 运行 函数,并每秒在控制台中打印一些随机 json 字符串。一开始他打印函数 simulateLED 的结果没有问题,但在休眠 1 秒后,我会得到一个 Segmentation Fault (Core dumped)。如果我删除睡眠,我就不会得到它并且程序运行正常。为什么我在休眠时会出现分段错误以及如何修复它?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char *simulateLED() {
int temp;
int luftf;
char* jsonString;
time_t t;
srand((unsigned) time(&t));
int x=-10, y=50;
temp=(rand()%((y+1)-x))+x;
x=2, y=30;
luftf=(rand()%((y+1)-x))+x;
printf("%d %d\n", temp, luftf);
fflush(stdout);
sprintf(jsonString, "{\n\"TEMP\": %d,\n\"HUMI\": %d\n}", temp, luftf);
return jsonString;
}
void *simAndSendThread(void *param) {
while(1) {
printf("%s", simulateLED());
sleep(1);
}
}
int main(int argc, char *argv[]) {
pthread_t thread;
if(pthread_create(&thread, NULL, simAndSendThread, NULL)) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
if(pthread_join(thread, NULL)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
pthread_exit(NULL);
return 0;
}
您尚未为 jsonString
分配内存,但仍在尝试执行 sprintf
以及在 return print
试试这个
char* jsonString;
jsonString = malloc( 1024 );
完成后别忘了 free
,您使用的是 while(1)
,如果您不使用 free
,您很有可能会点击 内存不足 错误很快。
如果你 enable full warnings
你应该收到一个 warning message for uninitialized variable
最终会避免所有的崩溃。
正如@DavidSchwartz 所指出的,Segmentation fault (core dumped)
错误的原因与当前未初始化的 jsonString
指针有关(即,未 指向 到任何东西)。因此,sprintf
正在写入一个随机位置,有时可能会或可能不会。
为了修复它,可以在声明的时候静态地把space赋值给jsonString
变量,比如:
...
char jsonString[256];
...
这意味着您可以拥有最多 255
个字符的字符串(1
个额外字符保留给 [=18=]
)。或者,您可以使用 malloc
:
...
char *jsonString = (char *)malloc(sizeof(char) * 256);
// Your code here
free(jsonString);
...
在这种情况下,你必须记得在你的函数结束时使用free
释放分配,否则你会泄漏内存。如果您还没有了解动态内存,请参阅 When and why to use malloc?。
P.S.: 如果你在Linux,我强烈建议你在出现内存相关错误时使用valgrind
。这个工具很可能会提示你在哪里犯了错误。查看 Valgrind Quick Start Guide 了解更多信息。