簡體   English   中英

字符串復制到malloc的char數組失敗,並出現分段錯誤

[英]string copy into malloc'd char array fails with segmentation fault

我正在用C練習一個客戶端-服務器應用程序。在該應用程序中,客戶端首先向服務器注冊,然后獲取client_id作為回報。 下次,客戶端將消息發送到服務器,在client_id之前添加消息。 下面的代碼段來自服務器,服務器在接收到消息后,從消息中檢索client_id ,這是一個3字符長的字符串,從消息數組中開始地址為1,結束地址為4。 例如。 在消息"1001CLIENT:001:MESSAGE:01" ,位置0處的“ 1”出於某種目的,“ 001”是client_id"CLIENT:001:MESSAGE:01"是來自客戶端的消息。

char *create_dynamic_string(int str_size)
{
        char *dyn_string = malloc(str_size*sizeof(char));
        if(!dyn_string)
        {
                printf("Dynamic string could not be created");
                return NULL;
        }
        dyn_string[0] = '\0';
        return dyn_string;
}

void free_dynamic_string(char *dyn_string)
{
        free(dyn_string);
}

//char *message is dynamically allocated char array.
char *retrieve_client_id(char *message)
{
        char *client_id;
        int i;
        client_id = create_dynamic_string(CLIENT_ID_SIZE + 1);

        if(!client_id)
        {
                printf("Client_id is NULL");
                return NULL;
        }
        //for(i = 1; i < (CLIENT_ID_SIZE + 1); i++)
        //      client_id[i-1] = message[i];

        //strncpy(client_id, message + 1, CLIENT_ID_SIZE);

        memcpy(client_id, message + 1, CLIENT_ID_SIZE);

        client_id[CLIENT_ID_SIZE] = '\0';
        printf("client_id retrieved=%s", client_id);
        return client_id;
}

服務器接受來自客戶端的連接,並在不同的線程中處理消息。 消息的多線程和處理工作已成功測試。 下面的代碼成功編譯並可以正常運行。 但是有時它最終會在retrieve_client_id() memcpy()處出現分段錯誤。 我無法弄清楚為什么會這樣失敗。

我用gdb獲取更多信息。 如下所示。

Program terminated with signal 11, Segmentation fault.
#0  0x00000000004017ef in retrieve_client_id (message=0x1b904f40 "1000CLIENT:000:MESSAGE:02") at src/server.c:46
46              memcpy(client_id, message + 1, CLIENT_ID_SIZE);
(gdb) print message
$1 = 0x1b904f40 "1000CLIENT:000:MESSAGE:02"
(gdb) print message+1
$2 = 0x1b904f41 "000CLIENT:000:MESSAGE:02"
(gdb) print CLIENT_ID_SIZE
$3 = 3
(gdb) print client_id
$4 = 0xffffffffcc0008c0 <Address 0xffffffffcc0008c0 out of bounds>
(gdb)               

需要幫助以了解當應用程序發生故障時到底會發生什么。 我已經驗證了malloc成功並且client_id不為NULL。 正如您看到的注釋代碼所示,我還嘗試了strcpy()並且還將字符從源一個一地復制到dest數組。 但是我也看到了失敗。

我猜create_dynamic_stringretrieve_client_id位於不同的編譯單元中,並且當后者編譯時,您沒有可見的正確原型。

該地址0xffffffffcc0008c0看起來像是一個合理的堆地址0xcc0008c0帶有附加的位。

添加此行:

extern char *create_dynamic_string(int);

正上方的定義retrieve_client_id

如果可以解決該問題(應解決),則將create_dynamic_string原型添加到適當的頭文件中,並將其#include到定義retrieve_client_id的源中。

我不明白為什么它沒有給出編譯錯誤

在C中,未聲明的函數假定具有以下原型:

int undeclared(...);

因此,以下任何通話均不會被拒絕:

int x = undeclared();
int y = undeclared(1);
char *z = undeclared(1, 2, 3);

您可以要求 GCC警告您有關缺少特定-Wmissing-prototypes ,但是最佳實踐是使用-Wall-Werror進行編譯。 后者不會讓您忽略警告並迫使您對其進行修復。

也建議添加-Wextra ,盡管有時它確實會給出假陽性警告。

暫無
暫無

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

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