strcpy() 上的分段错误;
segmentation fault on strcpy();
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
typedef struct client
{
int threadid;
int argc;
char *argv[3];
} client;
void exit(int status);
void error(char *msg);
void *threadClient(void *socket_desc);
int main(int argc, char *argv[])
{
client info[10];
pthread_t thread[10];
printf("%s\n%s\n%s\n", argv[0], argv[1], argv[2]);
// Error happens here
for (int i=0; i<=10; i++)
{
info[i].threadid = i;
strcpy(info[i].argv[0], argv[0]);
strcpy(info[i].argv[1], argv[1]);
strcpy(info[i].argv[2], argv[2]);
info[i].argc = argc;
printf("here");
if (pthread_create(&thread[i], NULL, threadClient, (void*)&info[i]) < 0)
{
perror("could not create thread");
return 1;
}
sleep(3);
}
pthread_exit(NULL);
return 0;
}
在循环期间,当我尝试将信息从 argv
复制到我的结构时,出现分段错误。为什么会这样?
Program received signal SIGSEGV, Segmentation fault.
__strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296
296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
您的结构定义为包含三个指针 (char *argv[3]
)。当您在堆栈中创建这些结构的数组时 (client info[10]
) space 是为这些指针保留的,等等。这些结构没有被初始化为任何东西,所以指针没有指向任何合理的内存位置。因此,像 strcpy(info[i].argv[0], argv[0]);
一样访问它们是错误的。
要么分配你显式使用的space:
info[i].argv[0] = malloc(strlen(argv[0])+1);
strcpy(info[i].argv[0], argv[0]);
或使用strdup()
复制字符串:
info[i].argv[0] = strdup(argv[0]);
记得free()
你之后分配的space。
此外,我认为您不应该自己声明一个名为 exit()
的函数,它是一个标准函数,应该在 stdlib.h
.
中
这里有两个问题。
首先,info
结构中的 argv
数组是一个指针数组。这些开始时未初始化。当您稍后调用 strcpy
时,将其中一个数组元素作为第一个参数,它期望该指针指向有效内存。所以你最终取消引用了一个未初始化的指针。这会调用 undefined behavior,在本例中表现为段错误。
你需要给这些指针赋值。您可以使用 strdup
复制这些字符串:
info[i].argv[0] = strdup(argv[0]);
info[i].argv[1] = strdup(argv[1]);
info[i].argv[2] = strdup(argv[2]);
或者,如果您不打算修改这些值,您可以直接复制指针值:
info[i].argv[0] = argv[0];
info[i].argv[1] = argv[1];
info[i].argv[2] = argv[2];
第二个问题是循环中的差一错误:
for (int i=0; i<=10; i++){
因为您使用 <=
,您的数组索引范围为 0 到 10。但是,您的数组只有 10 个元素(索引为 0 到 9),所以您写到最后的阵列。这也会调用未定义的行为。
将条件更改为 <
,如下所示:
for (int i=0; i<10; i++){
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
typedef struct client
{
int threadid;
int argc;
char *argv[3];
} client;
void exit(int status);
void error(char *msg);
void *threadClient(void *socket_desc);
int main(int argc, char *argv[])
{
client info[10];
pthread_t thread[10];
printf("%s\n%s\n%s\n", argv[0], argv[1], argv[2]);
// Error happens here
for (int i=0; i<=10; i++)
{
info[i].threadid = i;
strcpy(info[i].argv[0], argv[0]);
strcpy(info[i].argv[1], argv[1]);
strcpy(info[i].argv[2], argv[2]);
info[i].argc = argc;
printf("here");
if (pthread_create(&thread[i], NULL, threadClient, (void*)&info[i]) < 0)
{
perror("could not create thread");
return 1;
}
sleep(3);
}
pthread_exit(NULL);
return 0;
}
在循环期间,当我尝试将信息从 argv
复制到我的结构时,出现分段错误。为什么会这样?
Program received signal SIGSEGV, Segmentation fault. __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296 296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
您的结构定义为包含三个指针 (char *argv[3]
)。当您在堆栈中创建这些结构的数组时 (client info[10]
) space 是为这些指针保留的,等等。这些结构没有被初始化为任何东西,所以指针没有指向任何合理的内存位置。因此,像 strcpy(info[i].argv[0], argv[0]);
一样访问它们是错误的。
要么分配你显式使用的space:
info[i].argv[0] = malloc(strlen(argv[0])+1);
strcpy(info[i].argv[0], argv[0]);
或使用strdup()
复制字符串:
info[i].argv[0] = strdup(argv[0]);
记得free()
你之后分配的space。
此外,我认为您不应该自己声明一个名为 exit()
的函数,它是一个标准函数,应该在 stdlib.h
.
这里有两个问题。
首先,info
结构中的 argv
数组是一个指针数组。这些开始时未初始化。当您稍后调用 strcpy
时,将其中一个数组元素作为第一个参数,它期望该指针指向有效内存。所以你最终取消引用了一个未初始化的指针。这会调用 undefined behavior,在本例中表现为段错误。
你需要给这些指针赋值。您可以使用 strdup
复制这些字符串:
info[i].argv[0] = strdup(argv[0]);
info[i].argv[1] = strdup(argv[1]);
info[i].argv[2] = strdup(argv[2]);
或者,如果您不打算修改这些值,您可以直接复制指针值:
info[i].argv[0] = argv[0];
info[i].argv[1] = argv[1];
info[i].argv[2] = argv[2];
第二个问题是循环中的差一错误:
for (int i=0; i<=10; i++){
因为您使用 <=
,您的数组索引范围为 0 到 10。但是,您的数组只有 10 个元素(索引为 0 到 9),所以您写到最后的阵列。这也会调用未定义的行为。
将条件更改为 <
,如下所示:
for (int i=0; i<10; i++){