[英]Taking string input using pointers in c gives me segmentation fault in one function. Same block of code works fine for another function?
所以我想使用 char* 指針將名稱輸入作為字符串。 我在網上查看並找到了一個解決方案,方法是使用 malloc 給我的指針 memory 然后使用scanf
獲取輸入,如下所示:
char *userInput = (char*)malloc(20 * sizeof(char));
printf("\nEnter a name: ");
scanf("%s",userInput);
char *name = (char*)malloc(getLength(userInput)* sizeof(char));
name = userInput;
if(name == NULL){
printf("Memory not allocated");
exit(0);
}
free(userInput);
這行得通,所以我將它復制並粘貼到另一個需要類似輸入的 function 中:
char *userInput = (char*)malloc(20 * sizeof(char));
printf("\nEnter a name: ");
scanf("%s",userInput);
char *searched = (char*)malloc(getLength(searched)* sizeof(char));
searched = userInput;
if(searched == NULL){
printf("Memory not allocated");
exit(0);
}
free(userInput);
但是當我運行這個 function 的代碼時,它給了我“退出,分段錯誤”。
關於為什么它在我的第二個 function 中不起作用的任何想法?
編輯: getLength() 是一個 function ,它返回給定字符串的長度。
您在網上找到的代碼,如果您正確地復制它,是錯誤的。 問題是您正在釋放userInput
,即使searched
指向 memory。
您應該在釋放它之前將字符串從userInput
復制到searched
。
但是沒有必要對userInput
使用動態分配。 您可以只使用本地數組。
分配searched
時應該使用userInput
的長度。 並且您需要加 1 為 null 終結器留出空間。
在嘗試將userInput
復制到其中之前,您應該檢查分配是否成功。
char userInput[20];
printf("\nEnter a name: ");
scanf("%19s",userInput); // limit input length to 19 so it fits in userInput
char *searched = malloc((strlen(userInput)+1)* sizeof(char));
if(searched == NULL){
printf("Memory not allocated");
exit(0);
}
strcpy(searched, userInput);
這兩個代碼塊在這里有所不同:
char *name = (char*)malloc(getLength(userInput)* sizeof(char));
^^^^ ^^^^^^^^^
char *searched = (char*)malloc(getLength(searched)* sizeof(char));
^^^^^^^^ ^^^^^^^^^
第二種用途searched
了兩次。 因此,您可以正確修改原始代碼。
但是,請注意兩個代碼塊都是錯誤的。
代碼有幾個問題(兩個例子)。
scanf("%s",userInput);
真的很糟糕,因為它讓用戶溢出你的緩沖區。 看看fgets
或者至少做scanf("%19s",userInput);
這里:
char *name = (char*)malloc(getLength(userInput)* sizeof(char));
name = userInput;
malloc
行是無用的,因為您之后立即用userInput
覆蓋name
。 所以所有malloc
給你的是 memory 泄漏。
和這里
free(userInput);
您釋放userInput
指向的 memory。 但是,既然你做了name = userInput;
name
指向的也是memory。 所以在free之后,沒有一個指針是有效的。
我的猜測是,而不是:
name = userInput;
你會想要
strcpy(name, userInput);
也就是說 - 我不知道getLength
是什么,但也許malloc
應該是:
char *name = (char*)malloc(1 + getLength(userInput)* sizeof(char));
^^^
獲取 memory 用於字符串終止。 至少這是你在使用strlen
時所做的
所以:
char *userInput = malloc(20);
if(userInput == NULL){
printf("Memory not allocated");
exit(0);
}
printf("\nEnter a name: \n");
scanf("%19s",userInput);
char *searched = malloc(1 + strlen(userInput ));
if(searched == NULL){
printf("Memory not allocated");
exit(0);
}
strcpy(searched, userInput);
free(userInput);
但是......代碼的真正目的是什么?
似乎searched
應該保存(在動態分配的內存中)用戶輸入的字符串,並且動態分配的 memory 的數量應該正是保存字符串所需的量。
這在某些應用程序中可能有意義,但在您的情況下則不然!
第一個malloc
用於 20 個字符。 因此,第二個malloc
將用於 20 個或更少的字符。
Since malloc
has a memory overhead and some alignment requirement, the amount of real memory required by, eg malloc(20)
is more than 20 bytes. 換句話說 - malloc(20)
和malloc(10)
使用的實際 memory的差異可能很小。 所以代碼的整個想法是非常無用的 - 你不會通過執行第二個malloc
和字符串復制來節省大量的 memory 。
所以你應該簡單地做:
char *searched = malloc(20);
if(searched == NULL){
printf("Memory not allocated");
exit(0);
}
printf("\nEnter a name: \n");
scanf("%19s",searched);
// Go on using searched
...
...
// Somewhere later in the code, call free
free(searched);
僅當您的程序有時將很長的字符串作為輸入並且有時很短時,原始代碼才有意義。 在這種情況下,第一個malloc
將用於更大的數字,例如 1000000 個字符,然后將輸入復制到更小的緩沖區是有意義的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.