我在K& R c book之后编写了自己的getline
函数
void getline(char * const str)
{
int c;
char* temp = str;
while ((c=getchar()) != '\n') {
*temp = c;
temp++;
}
*temp = '\0'
}
它用于初始化字符串
char *str1, *str2;
printf("Type string 1: ");
getline(str1);
printf("Type string 2: ");
getline(str2);
只是想知道,如果内存位置str1
和str1
指向非常接近,那么getline(str2)
会覆盖字符串1中的内容吗?
可能我怎么能避免它呢?谢谢!
是的,程序停止执行上面的代码片段,但下面的代码有效:
#include <stdio.h>
main()
{
char* str;
char* temp = str;
int c;
while ((c=getchar()) != '\n') {
*temp = c;
++temp;
}
*temp = '\0';
printf("%s\n", str);
}
这里str
也是未初始化的字符指针,但是为什么它会让我错误?
答案 0 :(得分:3)
你拥有的是Undefined Behavior。
你宣布了两个指向char
的指针:
char *str1, *str2;
但你还没有初始化它们。他们指向一些&#34;随机&#34;内存位置,因为它们未初始化。
然后,您将str1
和str2
传递给getline
并在此处:
char* temp = str;
temp
指向str
指向的位置。然后,在循环中,
*temp = c;
你写到这个记忆位置。这会写入无效的内存位置。并调用UB。
您可以使用固定大小的自动数组:
char str1[101], str2[101];
请注意,您应该在getline
函数的循环中添加一个检查,当用户输入100个字符时,它会中断循环,这样就不会成为buffer overflow。
更好的解决方案是使用动态内存分配。您需要使用malloc
和realloc
。这些函数需要stdlib.h
标题。
固定代码 (未经测试):
char* getline()
{
char* str;
int c, size = 10, counter = 0;
str = malloc(size); /* Allocate `size` memory */
if(str == NULL)
{
printf("malloc failed to allocate memory");
exit(-1); /* Exit the program */
/* Or
return NULL;
*/
}
while ((c = getchar()) != '\n' && c != EOF) { /* Added check for EOF as well */
str[counter] = c;
counter++;
if(counter == size)
{
char* temp = str; /* Backup in case realloc fails */
size += 10; /* Which is the same as `size = size + 10` */
str = realloc(str, size); /* realloc size(20) memory */
if(str == NULL) /* If realloc failed */
{
printf("reallocing memory failed");
str = temp; /* str is NULL, retrieve the original contents */
break; /* Break out of the loop */
}
}
}
str = realloc(str, counter + 1); /* realloc `counter + 1` memory */
str[counter] = '\0';
return str;
}
并在调用函数中
char* str1 = getline();
if(str1)
puts(str1);
free(str1);
char* str2 = getline();
if(str2)
puts(str2);
free(str2);
答案 1 :(得分:0)
str1
和str2
未初始化,因此它将是未定义的行为。您可以访问不允许的内存,这会导致程序崩溃。
您必须为每个指针分配足够的内存并传递其大小以获取行函数,以确保您只在已分配的内存中写入。
答案 2 :(得分:0)
str1
和str2
未初始化。现在您在无效(或未授权)的内存位置调用 UB 编写(*temp = c;
)。
首先,您需要为str1
和str2
分配内存。
str1=malloc(100); // check return
str2=malloc(100);
能够写入该内存位置。
只是想知道,如果内存位置str1和str1指向非常接近,那么getline(str2)会覆盖字符串1中的内容吗?这有可能我怎么能避免呢?
就你而言,由这些malloc
分配的内存不会重叠(将是两个不同的传染性内存块),所以如果你也倾向于写超出这些内存位置,你将调用未定义的行为(如果幸运的话,分段错误)。所以,恕我直言,不会有str2
覆盖str1
的任何情况。