[英]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.