簡體   English   中英

C:使用 strcpy 將字符串分配給結構數組導致的段錯誤

[英]C: Segfault caused by assigning string to struct array using strcpy

我正在閱讀一個包含 10 行和 3 列的文本文件。 每個元素都需要放入一個數組中以進行進一步操作。 fileToArray 方法將挑選出每個字符串,我可以成功地單獨打印每個字符串,但是我似乎無法正確地將字符串分配給每個索引。

我的理解是我有一個指向 10 個 dataArrays 的指針,在我的 switch 語句中,本質上發生的是 dataArray[0].pName = P1... dataArray[1].pName = P2... etc... 和類似的結構中的其他變量。

文本文件最多有 10 行,因此為什么要初始化 10 個 arrays。

我的理解有缺陷還是我的代碼中有一些明顯的錯誤?

struct Processes
{
    char *pName;
    char *arvTime;
    char *srvTime;
};
void fileToArray(FILE *fp, struct Processes dataArray[])
{
    // temp[14] because 14 is the max size a line can be
    char temp[14];
    char delim[] = " \n";
    int count = 0;
    int a, b, c = 0;

    while(fgets(temp, 14, fp) != NULL)
    {
        char *ptr = strtok(temp, delim);

        while(ptr != NULL)
        {
            // printf("'%s'\n", ptr);
            // ^^^^ This line will successfully print out each string

            switch(count)
            {
            case 0:
                dataArray[a].pName = malloc(strlen(ptr + 1));
                strcpy(dataArray[a].pName, ptr);
                a++;
                count++;
                free(dataArray[a].pName);
                break;

            case 1:
                dataArray[b].arvTime = malloc(strlen(ptr + 1));
                strcpy(dataArray[b].arvTime, ptr);
                b++;
                count++;
                free(dataArray[b].arvTime);
                break;

            case 2:
                dataArray[c].srvTime = malloc(strlen(ptr + 1));
                strcpy(dataArray[c].srvTime, ptr);
                c++;
                count = 0;
                free(dataArray[c].srvTime);
                break;
            }


            ptr = strtok(NULL, delim);

        }
    }
}
int main(int argc, void *argv[])
{
    struct Processes dataArray[10];

    if(argc == 1)
    {
        FILE *fp;

        fp = fopen("process-data.txt", "r");

        fileToArray(fp, dataArray);

        fclose(fp);
    }
    return 0;
}
// Sample text file being read //
P1 1 5
P2 2 2
P3 11 5
P4 17 9
P5 3 1
P6 10 10
P7 4 3
P8 4 1
P9 7 8
P10 5 4

運行此代碼會導致段錯誤,我不確定原因。 查看其他類似的帖子,該解決方案似乎沒有使用 malloc() 這讓我認為我錯誤地實現了 function。

這段代碼的作用與您的想法完全相反

malloc(strlen(ptr + 1))

它不是為字符串分配足夠的空間,最后為 NUL 分配 1 個額外的空間,而是分配比字符串長度少 1 個的空間。 您想像這樣將+ 1移到strlen的調用之外

malloc(strlen(ptr)+1)

此外,您應該將ab的值初始化為 0 或更好,將abc成一個變量,並且僅在您讀入第三條信息時才增加它。

對於初學者,您應該將數組中的元素數傳遞給 function。 所以 function 聲明應該看起來像

void fileToArray( struct Processes dataArray[], size_t n, FILE *fp );

當 function 返回數組填充元素的數量時會更好。

size_t fileToArray( struct Processes dataArray[], size_t n, FILE *fp );

並且 function 至少可以稱為

size_t n = fileToArray( dataArray, 10, fp );

在這份聲明中

int a, b, c = 0;

只有變量c被初始化。 所有其他變量 a 和 b 均未初始化。 所以例如這個語句

dataArray[a].pName = malloc(strlen(ptr + 1));

導致未定義的行為。

這個表達

malloc(strlen(ptr + 1))

是無效的。 它相當於

malloc(strlen( &ptr[1] ))

並且在 memory 分配后立即釋放它是沒有任何意義的。

free(dataArray[a].pName);

function 可以通過以下方式定義

size_t fileToArray( struct Processes dataArray[], size_t n, FILE *fp )
{
    // temp[14] because 14 is the max size a line can be
    char temp[14];
    char delim[] = " \n";

    size_t i = 0;

    for( ; i < n && fgets( temp, sizeof( temp ), fp) != NULL; i++ )
    {
        dataArray[i].pName   = NULL;
        dataArray[i].arvTime = NULL;
        dataArray[i].srvTime = NULL;

        char *ptr = strtok( temp, delim );

        for( size_t j = 0; j < 3 && ptr != NULL; j++ )
        {
            switch ( j )
            {
            case 0:
                dataArray[i].pName = malloc( strlen( ptr ) + 1 );
                strcpy( dataArray[i].pName, ptr );
                break;

            case 1:
                dataArray[i].arvTime = malloc( strlen( ptr ) + 1 );
                strcpy( dataArray[i].arvTime, ptr );
                break;

            case 2:
                dataArray[i].srvTime = malloc( strlen( ptr ) + 1 );
                strcpy( dataArray[i].srvTime, ptr );
                break;
            }

            ptr = strtok( NULL, delim );
        }
    }

    return i;
}

暫無
暫無

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

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