簡體   English   中英

當我沒有使用malloc()分配足夠的內存時,為什么我的代碼可以工作?

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

我在SPOJ上正在執行此問題。 http://www.spoj.com/problems/NHAY/ 它需要動態地獲取輸入。 在下面的代碼中,即使我沒有使用malloc()將內存分配給char *needle malloc()我取l = 1但是我仍然可以接受任何長度的輸入,並且它正在打印出整個字符串。 有時會給出運行時錯誤。 當我沒有為字符串分配足夠的內存時,為什么會這樣?

#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);
    }
}

我還在stackoverflow上讀到一個字符串是char *所以我應該聲明char *needle 如何在代碼中使用這個事實? 如果我取l = 1那么無論輸入字符串的長度是多少,字符最多只能包含為char *指針分配的內存,即1個字節。 我怎樣才能做到這一點?

您的代碼通過sscanf將大於分配的空間的字符串復制到malloc分配的malloc產生了故意的緩沖區溢出。 之所以“有效”,是因為在大多數情況下,分配的緩沖區位於頁面中間的某個位置,因此“僅”將更多數據復制到緩沖區中會覆蓋相鄰數據。 C(和C ++)對純C數組不執行任何數組范圍檢查,因此未捕獲錯誤。

在出現運行時錯誤的情況下,您很可能會將字符串的一部分復制到未映射和未分配的內存中,這會觸發訪問沖突。

通常從基礎操作系統以固定大小的頁面分配內存。 例如,在x86系統上,頁面大小通常為4k。 如果您要寫入的映射地址距離頁面的開頭和結尾足夠遠,則整個字符串將適合頁面的邊界。 如果您足夠接近上限,則代碼可能會嘗試越過邊界進行寫操作,從而觸發訪問沖突。

[關於底層系統的一些假設]

它之所以可以工作,是因為C庫管理着操作系統中頁面中分配的內存池。 操作系統僅返回頁面。 C庫返回任意數量的數據。

對於第一次分配,您將獲得由操作系統分配並由池管理的讀/寫頁面。 您正在使用庫分配的數據的邊緣,但位於操作系統返回的頁面之內。

做您正在做的事情將破壞池的結構,使用動態內存的更廣泛的程序最終將崩潰。

C語言沒有默認的綁定檢查。 最好情況下,它將在調試時崩潰,有時它將按預期運行。 否則,您將最終覆蓋其他存儲塊。

它並不總是有效。 這是未定義的行為

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM