2017-09-23 54 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