我有一个作业,我必须接受用户的输入。我不能使用链表,只能使用数组,所以我的计划是:
-
分配一些内存。
-
如果我们需要重新分配,这意味着我达到了分配的单元格数量:
-
尝试重新分配。如果成功,那就太好了。
如果我们不能重新分配, 打印输入,释放内存和重新分配。
-
我真的无法决定告诉我如何到达分配的内存末尾的命令,这就是我需要您的帮助的原因。我写道:
if (i==(MAX_CHARS_INPUT-1))
但我不确定。
代码:
#include <stdio.h>
#include <stdlib.h>
#define MAX_CHARS_INPUT 200
#define D_SIZE 2
void printWithMalloc(){
int charSize=1;
int *ptr=malloc(MAX_CHARS_INPUT*sizeof(charSize));
int i=0, j=0, c;
printf("please enter a stringn");
while ((c=getchar())!=EOF && c!='n')
{
ptr[i++]=c;
if (i==(MAX_CHARS_INPUT-1)) /*if we need to realloc*/
{
int *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(charSize));
if (temp==NULL) /*realloc failed*/
{
printf("you wrote:n");
while(j<=i)
putchar(ptr[j++]);
free(ptr);
ptr=(int*)malloc(MAX_CHARS_INPUT*sizeof(charSize));
}
else
ptr=temp;
}
}
}
int main(){
printWithMalloc();
return 0;
}
谢谢!
问题确实出在您的状况上:
if (i==(MAX_CHARS_INPUT-1))
这有效,但仅在您第一次达到此限制时。当您realloc
缓冲区变大时,您不会检查该空间是否用完。所以想象一下我输入了 500 个字符。读取第 199 个字符时,缓冲区将重新分配为 400 个字符大。但是,i
仅在第 199 个字符处检查,因此当达到第 400 个字符时,它将耗尽缓冲区。
第二个问题是,当你重新分配缓冲区时,它只会增长到400个字符(D_SIZE * MAX_CHARS_INPUT
),不会更大。
第三个问题是当你重新malloc
时(即当realloc
失败时),你没有重置i
所以它会立即写入缓冲区的末尾。
正如现已删除的答案中所建议的那样。跟踪缓冲区大小:
size_t buffSize = MAX_CHARS_INPUT;
重新分配时,请先更新buffSize
,然后将其用作参数以realloc
:
buffSize *= D_SIZE; // double the buffer-size
temp = realloc(ptr, buffSize * sizeof(*temp)); // using sizeof *temp is less confusing and less error-prone
当然:还要更新您的状况:
if(i == buffSize - 1)
当您重新malloc
重置i
并buffSize
时:
buffSize = MAX_CHARS_INPUT;
ptr = malloc(buffSize*sizeof(*ptr));
i = 0;
虽然重新malloc
不是很明智,因为如果分配失败,通常会出现更大的问题(除非内存非常有限)。而且(特别是因为你不检查该malloc
的结果)可能有问题,因为该malloc
也可能失败。在分配失败后退出程序并不罕见。
你的代码中很少有错误,新代码是:
#include <stdio.h>
#include <stdlib.h>
#define MAX_CHARS_INPUT 200
#define D_SIZE 2
void printWithMalloc(){
//int charSize=1; you don't need this.
//int *ptr=malloc(MAX_CHARS_INPUT*sizeof(charSize));
char *ptr=malloc(MAX_CHARS_INPUT*sizeof(char));//sizeof(char) will give you the block size, MAX_CHARS_INPUT: gives you the number of blocks to be allocated and pointer type is char, since you want to save char(s), right?
int i=0, j=0, c;
printf("please enter a stringn");
//while ((c=getchar())!=EOF && c!='n')
while ((c=getchar())!='r') //'r' is for enter key... since the user input is coming from console not form a file, right?
{
ptr[i++]=c;
if (i==(MAX_CHARS_INPUT-1)) /*if we need to realloc*/
if (i==MAX_CHARS_INPUT) // i is already incremented in i++
{
//int *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(charSize));
char *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(char));
if (temp==NULL) /*realloc failed*/
{
printf("you wrote:n");
while(j<=i)
putchar(ptr[j++]);
free(ptr);
ptr=(char*)malloc(MAX_CHARS_INPUT*sizeof(char));
}
else
ptr=temp;
}
}
}
int main(){
printWithMalloc();
return 0;
}