簡體   English   中英

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復制到我的結構時,出現分段錯誤。 為什么會發生?

程序收到信號 SIGSEGV,分段錯誤。 __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296 296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:沒有這樣的文件或目錄。

這里有兩個問題。

首先,您的info結構中的argv數組是一個指針數組。 這些開始時未初始化。 當您稍后調用strcpy並將這些數組元素之一作為第一個參數時,它期望該指針指向有效內存。 所以你最終會取消引用一個未初始化的指針。 這會調用未定義的行為,在這種情況下表現為段錯誤。

您需要為這些指針分配一些東西。 您可以使用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++){

您的結構被定義為包含三個指針( char *argv[3] )。 當您在堆棧( client info[10] )中創建這些結構的數組時,會為這些指針等保留空間。 結構沒有初始化為任何東西,所以指針不指向任何合理的內存位置。 因此,像使用strcpy(info[i].argv[0], argv[0]);一樣訪問它們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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM