【问题标题】:segmentation fault on strcpy();strcpy() 上的分段错误;
【发布时间】:2017-09-17 14:09:41
【问题描述】:
#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 () 在 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296 296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:没有这样的文件或目录。

【问题讨论】:

  • 1) i&lt;=10 --> i&lt;10 2) strcpy(info[i].argv[0], argv[0]); info[i].argv[0] 未初始化。
  • 我改变了for循环我的问题谢谢我没有注意到我把它放在那里。但是我将如何初始化它?
  • info[i].argv[0] = malloc(strlen(argv[0])+1);strcpy 之前。

标签: c segmentation-fault strcpy


【解决方案1】:

您的结构被定义为包含三个指针 (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 中。

【讨论】:

    【解决方案2】:

    这里有两个问题。

    首先,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++){
    

    因为您使用&lt;=,所以您在数组中的索引范围为 0 到 10。但是,您的数组只有 10 个元素(索引为 0 到 9),因此您正在写入数组末尾。这也会调用未定义的行为。

    将条件更改为&lt;,如下所示:

    for (int i=0; i<10; i++){
    

    【讨论】:

      猜你喜欢
      • 2014-06-15
      • 1970-01-01
      • 2020-10-05
      • 2014-10-21
      • 2013-02-23
      • 2012-04-25
      • 2019-02-23
      • 2017-03-12
      • 2018-07-28
      相关资源
      最近更新 更多