在 c 中使用指针获取字符串输入使我在一个函数中出现分段错误。相同的代码块适用于另一个功能?
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 为我的指针提供内存,然后使用 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);
这有效,所以我将其复制并粘贴到另一个需要类似输入的函数,如下所示:
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);
但是当我 运行 这个函数的代码时,它给了我 "exited, segmentation fault"。
关于为什么它在我的第二个函数中不起作用的任何想法?
编辑:getLength() 是一个 returns 给定字符串长度的函数。
你在网上找到的代码,如果你复制正确,是错误的。问题是您正在释放 userInput
,即使 searched
指向该内存。
您应该在释放之前将字符串从 userInput
复制到 searched
。
但是 userInput
不需要使用动态分配。您可以只使用本地数组。
分配searched
时应使用userInput
的长度。并且您需要加 1 以便为空终止符留出空间。
在尝试复制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
给你的只是内存泄漏。
这里
free(userInput);
您释放 userInput
指向的内存。但是,由于您 name = userInput;
它 也是 name
指向的内存。所以释放后,none个指针是有效的。
我的猜测是,而不是:
name = userInput;
你会想要
strcpy(name, userInput);
就是说 - 我不知道 getLength
是什么,但也许 malloc
应该是:
char *name = (char*)malloc(1 + getLength(userInput)* sizeof(char));
^^^
为字符串终止获取内存。至少那是你在使用 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
应该保存(在动态分配的内存中)用户输入的字符串 并且 动态分配的内存量应该是需要保持字符串。
这在某些应用程序中可能有意义,但在您的情况下则不然!
第一个 malloc
是 20 个字符。因此,第二个 malloc
将用于 20 个或更少的字符。
由于 malloc
有内存开销和一些对齐要求,例如malloc(20)
超过 20 个字节。换句话说 - malloc(20)
和 malloc(10)
使用的 实际内存 的差异可能很小。所以代码的整个想法是非常无用的——你不会通过执行第二个 malloc
和字符串复制来节省大量内存。
所以你应该简单地做:
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 个字符,然后将输入复制到较小的缓冲区才有意义。
所以我想使用 char* 指针将名称输入作为字符串。
我在网上查看并找到了一个解决方案,方法是使用 malloc 为我的指针提供内存,然后使用 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);
这有效,所以我将其复制并粘贴到另一个需要类似输入的函数,如下所示:
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);
但是当我 运行 这个函数的代码时,它给了我 "exited, segmentation fault"。
关于为什么它在我的第二个函数中不起作用的任何想法?
编辑:getLength() 是一个 returns 给定字符串长度的函数。
你在网上找到的代码,如果你复制正确,是错误的。问题是您正在释放 userInput
,即使 searched
指向该内存。
您应该在释放之前将字符串从 userInput
复制到 searched
。
但是 userInput
不需要使用动态分配。您可以只使用本地数组。
分配searched
时应使用userInput
的长度。并且您需要加 1 以便为空终止符留出空间。
在尝试复制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
给你的只是内存泄漏。
这里
free(userInput);
您释放 userInput
指向的内存。但是,由于您 name = userInput;
它 也是 name
指向的内存。所以释放后,none个指针是有效的。
我的猜测是,而不是:
name = userInput;
你会想要
strcpy(name, userInput);
就是说 - 我不知道 getLength
是什么,但也许 malloc
应该是:
char *name = (char*)malloc(1 + getLength(userInput)* sizeof(char));
^^^
为字符串终止获取内存。至少那是你在使用 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
应该保存(在动态分配的内存中)用户输入的字符串 并且 动态分配的内存量应该是需要保持字符串。
这在某些应用程序中可能有意义,但在您的情况下则不然!
第一个 malloc
是 20 个字符。因此,第二个 malloc
将用于 20 个或更少的字符。
由于 malloc
有内存开销和一些对齐要求,例如malloc(20)
超过 20 个字节。换句话说 - malloc(20)
和 malloc(10)
使用的 实际内存 的差异可能很小。所以代码的整个想法是非常无用的——你不会通过执行第二个 malloc
和字符串复制来节省大量内存。
所以你应该简单地做:
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 个字符,然后将输入复制到较小的缓冲区才有意义。