[英]Why does this code to randomize a list of song names generate a segmentation fault?
我正在嘗試創建一個程序,該程序從用戶那里接收12個歌曲標題,然后以隨機順序形成一個列表。 我使用了gets()
函數和內存分配,以便將輸入放置到這樣的數組中:
argv[0] = song1, argv[1] = song2, argv[2] = song3 (etc.).
輸入實際的歌曲,然后通過randomize和createSetList()
函數運行它時,似乎存在常見的分段錯誤錯誤。 但是,如果要廢棄內存分配和硬代碼,它將可以正常工作。 我的意思是這樣的:
char *input[ SONG ] =
{ "song1", "song2", "song3", "song4",
"song5", "song6", "song7", "song8",
"song9", "song10", "song11", "song12", "song13" };
雖然,我的目的是讓用戶在運行時輸入歌曲名稱。 分段錯誤錯誤的原因是什么?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define SONG 13
#define SETSIZE 5
// prototypes
void randomize( unsigned int wDeck[ SONG ] );
void createSetList( unsigned int wDeck[ SONG ], char *wFace[] );
int main( void ){
printf("Please enter the songs you want to play!\n");
printf("I will create the set list and randomize it for you!\n");
char input[100];
char *argv[ SONG ];
char *token;
/*memory allocation for inputting song titles into a single array*/
/*****memory allocation code starts here********/
gets(input);
token = strtok(input, " ");
int i=0;
while( token != NULL ) {
argv[i] = malloc(strlen(token) + 1);
strncpy(argv[i], token, strlen(token));
i++;
token = strtok(NULL, " ");
}
argv[i] = NULL; //argv ends with NULL
/***memory allocation code ends here*****/
unsigned int setList[ SONG ] = { 0 };
srand( time( NULL ) ); // seed random-number generator
randomize( setList ); // shuffle the list
createSetList( setList, argv ); // create the setlist
} //end of main
/*SHUFFLE FUNCTION*/
void randomize( unsigned int wDeck[ SONG ] ){
size_t column;
size_t c;
for ( c = 1; c <= SETSIZE; ++c ) {
do {
column = rand() % SONG;
} while( wDeck[ column ] != 0 );
wDeck[ column ] = c;}}
/* Create Set List Function */
void createSetList( unsigned int wDeck[ SONG ], char *wFace[] ){
size_t c;
size_t column;
for ( c = 1; c <= SETSIZE; ++c ) {
for ( column = 0; column < SONG; ++column ) {
if ( wDeck[ column ] == c ) {
printf( "%s\n", wFace[ column ]);
}}}}
在您的代碼中
strncpy(argv[i], token, strlen(token));
用法是錯誤的。 您還需要復制終止的空字節。
從strncpy()
的手冊頁中可以看到
除了最多復制
n
個src
字節外,strncpy()
函數strncpy()
類似。警告:如果
src
的前n個字節中沒有空字節,則放置在dest
的字符串將不會以空終止。
如我的@chqrlie先生的評論中所述,並在@Keith Thompson的精彩文章中進行了解釋 ,您不應使用strncpy()
。 為了安全起見,可以使用strdup()
避免malloc()
+ strcpy()
的開銷( 和陷阱 strcpy()
。
偽碼
argv[i] = strdup(token);
將以有效的方式完成這項工作。 請記住,您仍然需要通過strdup()
來free()
返回的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.