[英]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)
此外,您應該將a
和b
的值初始化為 0 或更好,將a
、 b
和c
成一個變量,並且僅在您讀入第三條信息時才增加它。
對於初學者,您應該將數組中的元素數傳遞給 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.