[英]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.