2017-09-23 91 views
1

我正在嘗試編寫這個簡單的代碼,它將用戶輸入消息保存在堆棧中,然後再顯示給他。 我不想限制用戶輸入的字符數,所以每次用戶輸入新字符時都使用動態內存分配。動態分配內存以保存用戶輸入

如果用戶輸入小號碼,代碼運行良好。的字符,但它不起作用,如果用戶鍵入一個很大的號碼。的字符

例如:如果我輸入「艾哈邁德」它會顯示給我,但如果我輸入更多字符的東西它不。

這是我的代碼:

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

int main() 
{ 
    char *UserInput; 
    UserInput=(char *)calloc(1,sizeof(char)); 
    int i=0,ii=0; 
    printf("Enter a message! \n"); 
    while(*(UserInput+ii)!='\n'){ 
     scanf("%c",(UserInput+i)); 
     ii=i; 
     i++; 
     UserInput=realloc(UserInput,i*sizeof(char)); 
    } 
    for(i=0;i<=ii;i++){ 
     printf("%c",*(UserInput+i)); 
    } 

    return 0; 
} 
+1

1)'int i = 0' - >'int i = 1'(因爲'i'代表安全大小) – BLUEPIXY

+0

感謝您提出這個意見。當用戶輸入的垃圾初始值爲'\ n'時,我添加了初始化來避免重合,所以我添加了這個初始化'* UserInput ='1';' – Ahmed

+0

主要問題是'realloc'時的大小。修復像[this](https://ideone.com/ErKreS) – BLUEPIXY

回答

1

更改過自己的計劃進行正常運行:

UserInput=realloc(UserInput,((i + 1)*sizeof(char)); 

說明:

當你被scanf接受輸入,您正在接收一系列字符(包括'\n')。由於您的格式說明符是%c,它應該只接受一個字符。輸入不是單個字符,而是一個字符序列。另外%c不會過濾掉'\n'。多餘的字符被存儲到scanf的緩衝區中。下一次調用scanf時,它會從緩衝區獲取輸入。

,由calloc你在一開始分配的空間UserInput 1個字節,但是當你在每次迭代中的字符調用scanf函數存儲在UserInput + 1個位置,這沒有被釋放calloc分配到您的變量,但是它仍然處於calloc的緩衝區,即它仍然沒有觸及系統內存/堆。在迭代結束時你會記住你的記憶。即您正在使用未分配的內存,然後將其分配給UserInput。

對於小的字符序列,這將不會給任何錯誤,釋放calloc的緩衝區不小,但對於大的字符序列,你會得到一個錯誤 - 「損壞的尺寸與prev_size」 - 這是一個指標heap attack/exploitation.

發生這種情況是因爲calloc緩衝區現在已耗盡,並且您正在使用系統堆中的內存,從而將系統發送至狂熱。您修改了分配給您使用的範圍之外的內存,並且系統發現其控制數據已損壞,並且對此並不滿意。

也不要忘了free(UserInput);

普羅斯特!

+0

感謝這個很好的解釋,你已經幫了很多:D – Ahmed