简体   繁体   English

当我没有使用malloc()分配足够的内存时,为什么我的代码可以工作?

[英]Why is my code working when I haven't allocated enough memory using malloc()?

I have I am doing this problem on SPOJ. 我在SPOJ上正在执行此问题。 http://www.spoj.com/problems/NHAY/ . http://www.spoj.com/problems/NHAY/ It requires taking input dynamically. 它需要动态地获取输入。 In the code below even though I am not allocating memory to char *needle using malloc() - I am taking l = 1 - yet I am able to take input of any length and also it is printing out the entire string. 在下面的代码中,即使我没有使用malloc()将内存分配给char *needle malloc()我取l = 1但是我仍然可以接受任何长度的输入,并且它正在打印出整个字符串。 Sometimes it gives runtime error. 有时会给出运行时错误。 Why is this when I have not allocated enough memory for the string? 当我没有为字符串分配足够的内存时,为什么会这样?

#include<stdio.h>
#include<malloc.h>
#include<ctype.h>
#include<stdlib.h>

int main()
{
    long long l;
    int i;
    char *needle;
    while(1){
        scanf("%lld",&l);
        needle =(char *)malloc(sizeof(char)*l);
        scanf("%s",needle);
        i=0;
        while(needle[i]!='\0'){
            printf("%c",needle[i]);
            i++;
        }
        free(needle);
    }
}

I also read on stackoverflow that a string is a char * so I should declare char *needle . 我还在stackoverflow上读到一个字符串是char *所以我应该声明char *needle How can I use this fact in the code? 如何在代码中使用这个事实? If I take l = 1 then no matter, what the length of the input string it should contain characters only up to the memory allocated for the char * pointer, ie 1 byte. 如果我取l = 1那么无论输入字符串的长度是多少,字符最多只能包含为char *指针分配的内存,即1个字节。 How can I do that? 我怎样才能做到这一点?

Your code is producing an intentional buffer overflow by having sscanf copying a string bigger than the allocated space into the memory allocated by malloc . 您的代码通过sscanf将大于分配的空间的字符串复制到malloc分配的malloc产生了故意的缓冲区溢出。 This "works" because in most cases, the buffer that is allocated is somewhere in the middle of a page so copying more data into the buffer "only" overwrites adjacent data. 之所以“有效”,是因为在大多数情况下,分配的缓冲区位于页面中间的某个位置,因此“仅”将更多数据复制到缓冲区中会覆盖相邻数据。 C (and C++) don't do any array bounds checking on plain C array and thus the error is uncaught. C(和C ++)对纯C数组不执行任何数组范围检查,因此未捕获错误。

In the cases where you end up with a runtime error, you most likely copied part of the string into unmapped and unallocated memory, which trigger an access violation. 在出现运行时错误的情况下,您很可能会将字符串的一部分复制到未映射和未分配的内存中,这会触发访问冲突。

Memory is usually allocated from the underlying OS in pages of a fixed size. 通常从基础操作系统以固定大小的页面分配内存。 For example, on x86 systems, pages are usually 4k in size. 例如,在x86系统上,页面大小通常为4k。 If the mapped address you are writing to is far enough away from the beginning and end of the page, the whole string will fit within the boundaries of the page. 如果您要写入的映射地址距离页面的开头和结尾足够远,则整个字符串将适合页面的边界。 If you get close enough to the upper boundary, the code may attempt to write past the boundary, triggering the access violation. 如果您足够接近上限,则代码可能会尝试越过边界进行写操作,从而触发访问冲突。

[With some assumptions about the underlying system] [关于底层系统的一些假设]

The reason it works for now is that the C library manages pools of memory allocated in pages from the operating system. 它之所以可以工作,是因为C库管理着操作系统中页面中分配的内存池。 The operating system only returns pages. 操作系统仅返回页面。 The C library returns arbitrary amounts of data. C库返回任意数量的数据。

For your first allocation, you are getting read/write pages allocated by the operating system and managed by the pool. 对于第一次分配,您将获得由操作系统分配并由池管理的读/写页面。 You are going off the edge of the data allocated by the library but are within the page returned by the operating system. 您正在使用库分配的数据的边缘,但位于操作系统返回的页面之内。

DOing what you are doing will corrupt the structure of the pool and a more extensive program using dynamic memory will eventually crash. 做您正在做的事情将破坏池的结构,使用动态内存的更广泛的程序最终将崩溃。

C language do not have default bound check. C语言没有默认的绑定检查。 At the best it will crash while debugging, sometimes it will work as expected. 最好情况下,它将在调试时崩溃,有时它将按预期运行。 Otherwise you will end up overwriting other memory blocks. 否则,您将最终覆盖其他存储块。

It will not always work. 它并不总是有效。 It is Undefined Behaviour . 这是未定义的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我没有分配空间时,为什么可以读写内存? - Why can I write and read memory when I haven't allocated space? 为什么malloc()不分配足够的内存 - Why Isn't malloc() Allocating Enough Memory 为什么malloc没有分配足够的内存? - Why doesn't malloc allocate enough memory? 当有足够的内存时,为什么malloc()失败? - Why does malloc() fail when there is enough memory? 为什么在运行malloc代码之前分配内存? - Why is memory being allocated before malloc code has run? 为什么C中没有“memsize”,它返回使用malloc在堆中分配的内存块的大小? - Why isn't there a “memsize” in C which returns the size of a memory block allocated in the heap using malloc? 为什么内核不清除进程中第二个 malloc 分配的内存? - Why doesn't kernel clear the memory allocated by second malloc in a process? 太多的内存被分配,以至于当我的程序运行得足够深时,我被“杀死” - So much memory being malloc'd that I get “Killed” when running my program deep enough 为什么没有释放分配了malloc的虚拟内存? - Why is virtual memory allocated with malloc not released? 如何在以下代码中释放分配给malloc的内存? - how to deallocate the memory allocated to the malloc in following code?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM