gets()如何超过malloc()分配的内存?
当我将malloc函数用于 为字符指针分配10字节的内存。但是当我赋值的时候 对于该字符指针,如果我尝试分配,它需要超过10个字节。这是怎么可能的 例如:gets()如何超过malloc()分配的内存?,c,C,当我将malloc函数用于 为字符指针分配10字节的内存。但是当我赋值的时候 对于该字符指针,如果我尝试分配,它需要超过10个字节。这是怎么可能的 例如: main() { char *ptr; ptr=malloc(10*sizeof(char)); gets("%s",ptr); printf("The String is :%s",ptr); } 样本输出: $./a.out hello world this is for testing 字符串是:he
main()
{
char *ptr;
ptr=malloc(10*sizeof(char));
gets("%s",ptr);
printf("The String is :%s",ptr);
}
样本输出:
$./a.out
hello world this is for testing
字符串是:hello world这是用于测试的
现在看看输出,字符数超过10字节。
这怎么可能,我需要清楚的解释。
提前感谢。这就是为什么使用
get
是件坏事。改用fgets
malloc
与此无关
.
诚然,理论基础是有用的,是吗?首先,get()
不允许您指定用于存储字符串的缓冲区的长度。这将允许人们在缓冲区结束后继续输入数据,相信我,这将是个坏消息
:
首先,让我们看看这个函数的原型:
#include <stdio.h>
char *gets(char *s);
我们可以将其传递给get()
,如下所示:
gets(buf)
到目前为止,一切顺利。或者看起来是这样。。。但实际上,我们的问题已经开始了gets()
只收到数组(指针)的名称,它不知道数组有多大,,单从指针无法确定。当用户输入文本时,get()
会将所有可用数据读取到数组中,如果用户明智且输入的字节数少于99字节,则这将是正常的。但是,如果它们输入的值超过99,get()
将不会停止在数组末尾写入。取而代之的是,它会继续写到它不拥有的内存中
你只是有一个未定义的行为。()
使用fgets而不是get malloc将保留10个字节(假设char有1个字节),并返回保留区域的起点。
您执行一个
获取
,因此它获取您键入的文本,并使用指针写入。
Windows/Mac os x/Unix(高级操作系统)具有受保护的内存。
这意味着,当您执行malloc/new操作时,操作系统会为您的程序保留该内存区域。如果另一个程序试图在该区域写入,则会发生分段错误,因为您在不应写入的区域上写入
您保留了10个字节。
如果字节11、12、13、14尚未保留给其他程序,则不会崩溃,如果是,则您的程序将访问受保护区域并崩溃。
malloc
保留内存供您使用。规则是允许您使用以这种方式和其他方式分配的内存(如定义自动或静态对象),并且不允许您使用未分配给您使用的内存
但是,malloc
和操作系统并不完全执行这些规则。遵守这些规则的义务属于您,而不是malloc
或操作系统
通用操作系统具有内存保护,可防止一个进程未经允许读取或更改另一个进程的内存。它不会阻止一个进程以不正确的方式读取或更改自己的内存。当您访问不应该访问的字节时,没有任何机制可以始终防止这种情况。内存在那里,您可以访问它,但是您不应该访问它
get
是一个设计糟糕的例程,因为如果输入行足够长,它将写入任意数量的内存。这意味着您无法阻止它写入超过您分配的内存。您应该改用fgets
。它有一个参数限制它可以写入的内存量
通用操作系统以称为页的块分配内存。页面的大小可能是4096字节。当malloc
为您分配内存时,它可以从操作系统获得的最小大小是一页。当您请求10个字节时,malloc
将获得一个页面,如果需要,在其中选择10个字节,记录页面的一小部分已分配,但其余部分可供其他使用,并将指向该10个字节的指针返回给您。当您进行进一步分配时,malloc
可能会从同一页分配额外的字节
当您超出分配给您的字节数时,您违反了规则。如果进程的其他部分没有使用这些字节,那么您可能不会受到这种违规行为的影响。但您可能会更改malloc用来跟踪分配的数据,您可能会更改作为单独内存分配一部分的数据,或者,如果您做得足够深入,您可能会完全更改单独页面中的数据,并且这些数据正由程序的完全不同部分使用
通用操作系统确实提供了一些保护,防止进程中内存的不当使用。如果尝试访问虚拟地址空间中未映射的页面,或者尝试修改标记为只读的页面,则会触发错误,并且进程将中断。但是,此保护仅适用于页面级别,不会防止您错误地使用分配给进程的内存。OP:。。。字符数超过10个字节。
gets(buf)