strcpy()上的分段错误;

时间:2017-04-20 19:13:40

标签: c segmentation-fault 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复制到我的结构时,我遇到了分段错误。为什么会这样?

  

编程接收信号SIGSEGV,分段故障。   __strcpy_sse2_unaligned()at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296   296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:没有这样的文件或目录。

2 个答案:

答案 0 :(得分:1)

这里有两个问题。

首先,argv结构中的info数组是一个指针数组。这些开始是未初始化的。当您稍后调用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++){

答案 1 :(得分:0)

您的结构被定义为包含三个指针(char *argv[3])。当您在堆栈中创建这些结构的数组(client info[10])时,会为这些指针保留空间,以及其他内容。结构不是任何东西,所以指针不指向任何合理的内存位置。因此,与strcpy(info[i].argv[0], argv[0]);一样访问它们是错误的。

分配明确使用的空间:

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()之后分配的空间。

此外,我认为您不应该自己声明一个名为exit()的函数,它是一个标准函数,应该在stdlib.h中。