gpt4 book ai didi

c - 在c中为数组动态分配内存时的停止条件

转载 作者:行者123 更新时间:2023-11-30 14:32:42 26 4
gpt4 key购买 nike

我从输入中获取一个数组,当没有更多内存时,我分配更多内存(我不能使用 realloc)。我的问题是我不知道该将什么作为循环的停止条件。我希望它在我按 Enter 时停止接受输入,但它只是等待更多。(我应该使用 scanf)

我的代码:

#include<stdio.h>
#include<stdlib.h>
#define CHUNK 5
int main()
{
int *arr, allocate_size=0, i, j, k, temp=0, *p, len=0;
printf("Enter array: ");
for(i=0,j=0;temp!='\n';i++){
if(i>=allocate_size){
allocate_size+= ((++j)*CHUNK);
p = (int*)malloc(sizeof(int)*allocate_size);
if(p==NULL){
printf("Error");
return 1;
}
for(k=0;k<i && i!=0;k++){ /*copying array*/
p[k]=arr[k];
}
free(arr);
arr = p;
}
if(!scanf(" %d", &temp)){
printf("Invalid input");
return 1;
}
if(temp!='\n'){
arr[i] = temp;
len++;
}
}
printf("length is %d\n", len);
for(i=0;i<len;i++){
printf("%d",arr[i]);
}
return 0;
}

最佳答案

获取用户输入的首选方法是使用 fgets() 或 POSIX getline() 一次读取整行输入。原因是每次读取都会消耗一整行输入,而 stdin 中保留的内容并不取决于所使用的 scanf 转换说明符 。它还无需记住哪些转换说明符消耗前导空格,哪些不消耗前导空格,并消除在匹配失败时留在stdin中的字符。

它还可以方便地检查用于保存输入的缓冲区中的第一个字符是否是 '\n' 告诉您 Enter 单独是在没有任何其他输入的情况下按下。

要在代码中使用 fgets()sscanf(),只需声明一个缓冲区来保存一行用户输入,足以满足用户的任何需求输入(或者如果猫踩在键盘上会产生什么结果)——不要吝惜缓冲区大小。然后使用 fgets() 将输入读入缓冲区,并检查第一个字符是否为 '\n' 以确定是否单独按下了 Enter .

您可以按如下方式执行此操作:

int main()
{
char buf[256];
...
if (!fgets (buf, sizeof buf, stdin)) { /* read line of input/validate */
fputs ("(user canceled input)\n", stderr);
return 1;
}
if (buf[0] == '\n') /* break loop on [Enter] alone */
break;
if (sscanf (buf, "%d", &temp) != 1) {
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
...

(注意:检查 sscanf (buf, "%d", &temp) != 1 将捕获手动生成的 EOF如果用户按 Ctrl+d(或在 Windows 上按 Ctrl+z),则 !sscanf(buf, "%d", &temp) 获胜't)

仔细检查一下,如果您还有其他问题,请告诉我。

<小时/>

编辑每条评论

因为在您的问题中,您表明必须为每个读取的整数动态分配,但您不能使用 realloc 来调整数组大小,这是双指针 arr 的唯一逻辑假设code> 和 p 是,您应该通过每次使用 p 分配存储来手动实现 realloc,通过以下方式保存指向分配 block 的指针在每次迭代结束时从 arr = p; 进行赋值,以便您可以从 arr 复制到您在下一次迭代中分配的新 p 并然后在再次分配 arr = p; 之前释放 arr 以防止内存泄漏

将上述解决方案与您发布的代码放在一起,您可以执行类似于以下操作的操作:

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

#define CHUNK 5
#define MAXC 256

int main (void)
{
char buf[MAXC] = ""; /* buffer to hold each line */
int *arr = NULL, /* pointer to block holding final array */
*p = NULL, /* temp pointer to allocate for each number */
allocate_size = 0, /* tracks length of array */
temp = 0; /* temp value for integer conversion */

printf ("Enter %d elements of array:\n\n arr[%d]: ", CHUNK, allocate_size);

while (fgets (buf, MAXC, stdin)) { /* read user input into buf */
int rtn; /* variable to hold sscanf return */

if (*buf == '\n') /* check if ENTER alone */
break; /* break loop if so */

/* use sscanf to convert to int, saving return */
if ((rtn = sscanf (buf, "%d", &temp)) == 1) {
/* allocate new storage for allocate_size + 1 integers */
if (!(p = malloc ((allocate_size + 1) * sizeof *p))) {
perror ("malloc-p");
break;
}
for (int i = 0; i < allocate_size; i++) /* copy arr to p */
p[i] = arr[i];
p[allocate_size++] = temp; /* add new element at end */

free (arr); /* free old block of memory */
arr = p; /* assign new block to arr */
}
else if (rtn == EOF) { /* manual EOF generated */
fputs ("(user canceled input)\n", stderr);
break;
}
else { /* not an integer value */
fputs ("error: invalid integer input.\n", stderr);
}

if (allocate_size < CHUNK) /* if arr not full, prompt for next */
printf (" arr[%d]: ", allocate_size);
else
break; /* done */
}

/* output results */
printf ("\nlength is %d\n", allocate_size);
for (int i = 0; i < allocate_size; i++)
printf (" %d", arr[i]);
putchar ('\n');

free (arr); /* don't forget to free what you allocate */
}

示例使用/输出

没有停止或错误:

$ ./bin/arrnorealloc
Enter 5 elements of array:

arr[0]: 10
arr[1]: 20
arr[2]: 30
arr[3]: 40
arr[4]: 50

length is 5
10 20 30 40 50

提早停止:

$ ./bin/arrnorealloc
Enter 5 elements of array:

arr[0]: 10
arr[1]: 20
arr[2]:

length is 2
10 20

处理用户错误:

$ ./bin/arrnorealloc
Enter 5 elements of array:

arr[0]: 10
arr[1]: 20
arr[2]: dogs
error: invalid integer input.
arr[2]: 30
arr[3]: fish
error: invalid integer input.
arr[3]: 40
arr[4]: 50

length is 5
10 20 30 40 50

内存使用/错误检查

最重要的是动态分配内存时,错误检查:

$ valgrind ./bin/arrnorealloc
==5555== Memcheck, a memory error detector
==5555== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5555== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5555== Command: ./bin/arrnorealloc
==5555==
Enter 5 elements of array:

arr[0]: 10
arr[1]: 20
arr[2]: 30
arr[3]: 40
arr[4]: 50

length is 5
10 20 30 40 50
==5555==
==5555== HEAP SUMMARY:
==5555== in use at exit: 0 bytes in 0 blocks
==5555== total heap usage: 7 allocs, 7 frees, 2,108 bytes allocated
==5555==
==5555== All heap blocks were freed -- no leaks are possible
==5555==
==5555== For counts of detected and suppressed errors, rerun with: -v
==5555== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放分配的所有内存并且不存在内存错误。

关于c - 在c中为数组动态分配内存时的停止条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59701788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com