[英]possibility of memory overwrite using pointers in c?
I've written my own getline
function following K&R c book 我在K&R c书之后写了自己的
getline
函数
void getline(char * const str)
{
int c;
char* temp = str;
while ((c=getchar()) != '\n') {
*temp = c;
temp++;
}
*temp = '\0'
}
and it's used to initialize strings 它用于初始化字符串
char *str1, *str2;
printf("Type string 1: ");
getline(str1);
printf("Type string 2: ");
getline(str2);
Just wonder that, what if the memory locations str1
and str1
point to are very close, then getline(str2)
overwrites contents in string 1? 只是想知道,如果存储位置
str1
和str1
指向的位置非常接近,那么getline(str2)
覆盖字符串1中的内容怎么办?
It that's possible how could I avoid it? 有可能我怎么避免呢? THANKS!
谢谢!
Yes the program stops executing the above code snippet but the code below works: 是的,程序停止执行上述代码片段,但以下代码有效:
#include <stdio.h>
main()
{
char* str;
char* temp = str;
int c;
while ((c=getchar()) != '\n') {
*temp = c;
++temp;
}
*temp = '\0';
printf("%s\n", str);
}
Here the str
is also uninitialized character pointer but why deoesn't it give me an error? 这里的
str
也是未初始化的字符指针,但是为什么它不会给我一个错误?
What you have is Undefined Behavior . 您拥有的是未定义行为 。
You declared two pointers to char
: 您声明了两个指向
char
指针:
char *str1, *str2;
but you haven't initialized them. 但您尚未初始化它们。 They point to some "random" memory location as they are uninitialized.
它们指向未初始化的某个“随机”存储位置。
Then, you pass str1
and str2
to getline
and here: 然后,将
str1
和str2
传递到getline
以及此处:
char* temp = str;
temp
points to where str
points to. temp
指向str
指向的位置。 Then, in the loop, 然后,在循环中
*temp = c;
you write to this memory location. 您写入此存储位置。 This writes into an invalid memory location.
这将写入无效的内存位置。 And invokes UB .
并调用UB 。
You can use an automatic array with a fixed size: 您可以使用固定大小的自动数组:
char str1[101], str2[101];
Note that you should add a check in the loop in the getline
function which breaks the loop when the user has entered 100 characters so that there won't be a buffer overflow . 请注意,您应该在
getline
函数的循环中添加一个检查,当用户输入100个字符时,该循环会中断循环,以免缓冲区溢出 。
A better solution would be to use dynamic memory allocation. 更好的解决方案是使用动态内存分配。 You need to use
malloc
and realloc
for that. 您需要为此使用
malloc
和realloc
。 These functions require the stdlib.h
header. 这些功能需要
stdlib.h
标头。
Fixed code (untested) : 固定代码 (未经测试) :
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; }
and in the calling function, 在调用函数中
char* str1 = getline(); if(str1) puts(str1); free(str1); char* str2 = getline(); if(str2) puts(str2); free(str2);
str1
and str2
are not initialized thus it'll be undefined behaviour. str1
和str2
未初始化,因此将是未定义的行为。 You can access to not allowed memory which will crash your program. 您可以访问不允许的内存,这将使您的程序崩溃。
You have to allocate enough memory for each pointer and pass its size to get line function to ensure you write only in allocated memory. 您必须为每个指针分配足够的内存,并传递其大小以获取行函数,以确保仅在分配的内存中写入。
str1
and str2
are uninitialized.Right now you write ( *temp = c;
) at invalid (or unauthorized) memory location invoking UB . str1
和str2
初始化。现在,您在调用UB的无效(或未授权)存储位置写入( *temp = c;
)。
First you need to allocate memory to str1
and str2
. 首先,您需要为
str1
和str2
分配内存。
str1=malloc(100); // check return
str2=malloc(100);
To be able to write into that memory location. 为了能够写入该内存位置。
Just wonder that, what if the memory locations str1 and str1 point to are very close, then getline(str2) overwrites contents in string 1?It that's possible how could I avoid it?
只是想知道,如果内存位置str1和str1指向的位置非常接近,那么getline(str2)会覆盖字符串1中的内容,那怎么可能呢?
And as far as you concern , memory allocated by these malloc
won't overlap (will be two different contagious memory blocks) , so if you also tend to write beyond these memory location ,you will invoke undefined behaviour ( if you are lucky segmentation fault ) . 而且就您而言,由这些
malloc
分配的malloc
不会重叠(将是两个不同的可感染内存块),因此,如果您还倾向于写超出这些内存位置的内容,则会调用未定义的行为 ( 如果您遇到了幸运的分段错误) )。 So, IMHO, there won't be any case of str2
over-writing str1
. 因此,恕我直言,不会发生
str2
覆盖str1
任何情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.