我按照K&R; c的书写了我自己的getline
函数
void getline(char * const str)
{
int c;
char* temp = str;
while ((c=getchar()) != 'n') {
*temp = c;
temp++;
}
*temp = ' '
}
用来初始化字符串
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 = ' ';
printf("%sn", str);
}
这里的str
也是未初始化的字符指针,但为什么不给我一个错误?
你拥有的是未定义行为
<标题>解释:声明了两个指向char
的指针:
char *str1, *str2;
但是你还没有初始化它们。它们指向一些"随机的";未初始化时的内存位置
然后,将str1
和str2
传递给getline
,这里:
char* temp = str;
temp
指向str
所在的位置。然后,在循环中,
*temp = c;
你写到这个内存位置。这将写入无效的内存位置。并调用UB。
<标题>修复:你可以使用一个固定大小的自动数组:
char str1[101], str2[101];
注意,你应该在
getline
函数的循环中添加一个检查,当用户输入了100个字符时,它会打破循环,这样就不会有缓冲区溢出。一个更好的解决方案是使用动态内存分配。您需要使用
<<p> 固定代码/strong> (未测试):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] = ' '; return str; }
和调用函数
char* str1 = getline(); if(str1) puts(str1); free(str1); char* str2 = getline(); if(str2) puts(str2); free(str2);
str1
和str2
没有初始化,因此它将是未定义的行为。你可以访问不允许的内存,这会使你的程序崩溃。
您必须为每个指针分配足够的内存,并将其大小传递给get line函数,以确保您只在分配的内存中写入
str1
和str2
未初始化。现在你写(*temp = c;
)在无效的(或未经授权的)内存位置调用UB。
首先,您需要为str1
和str2
分配内存。
str1=malloc(100); // check return
str2=malloc(100);
能够写入该内存位置。
只是想知道,如果内存位置str1和str1指向非常接近,那么getline(str2)覆盖字符串1中的内容?如果有可能,我怎么能避免呢?
就你而言,这些malloc
分配的内存不会重叠(将是两个不同的传染性内存块),所以如果你也倾向于在这些内存位置之外写,你将调用未定义行为 (如果你幸运的话分段错误)。所以,恕我直言,不会有任何str2
覆盖str1
的情况。