您面对的经典案例是“如何读取未知数量的X?”。答案是简单地使用malloc
(或calloc
或realloc
)分配一些初始数量的元素,并跟踪您拥有的allocated
,然后跟踪元素数量{{ 1}}(已填充)。当used
时,您used == allocated
数组并将可用元素的数量增加一定数量,或者每次增加一些固定数量,或者增加一些当前数量。元素数量加倍是分配增长和所需重新分配数量的相当不错的平衡。
一个简单的示例,用realloc
读取未知数目的双精度数,然后输出读取的数字和总和可能是:
scanf
(注意:您总是#include <stdio.h>
#include <stdlib.h>
int main (void) {
size_t used = 0,allocated = 2; /* used doubles/allocated doubles */
double *arr,sum = 0.0; /* array & sum of elements */
/* allocate initial 'allocated' number of doubles */
if (!(arr = malloc (allocated * sizeof *arr))) {
perror ("malloc-arr");
return 1;
}
while (scanf ("%lf",&arr[used]) == 1) { /* read doubles until EOF */
sum += arr[used++]; /* add to sum,increment used */
if (used == allocated) { /* if used == allocated */
/* reallocate more doubles using a temporary pointer */
void *tmp = realloc (arr,2 * allocated * sizeof *arr);
if (!tmp) { /* validate reallocation */
perror ("realloc-tmp");
break; /* don't exit,original arr still good,break */
}
arr = tmp; /* assign reallocated block to arr */
allocated *= 2; /* update number allocated */
}
}
printf ("%zu doubles entered with sum: %.2f\n",used,sum);
free (arr); /* free the memory you have allocated */
}
到临时指针,因为如果realloc
失败,它将返回realloc
覆盖原始指针地址,从而使您无法能够访问或NULL
realloc`确实失败,通过使用临时指针,您的现有数据将通过原始指针保留)
您现在可以将free() the original block resulting in a *memory leak*. If
及其包含的元素数(arr
)传递给需要该信息的任何函数。
使用/输出示例
used
或从文件中重定向10,000个浮点值:
$ ./bin/sumdoubles
1.1
2.2
3.3
4.4
5.5
6.6
7.7
8.8
9.9
9 doubles entered with sum: 49.50
内存使用/错误检查
在您编写的任何动态分配内存的代码中,对于任何分配的内存块,您都有2个职责:(1)始终保留指向起始地址的指针因此,(2)当不再需要它时可以释放。
当务之急是使用一个内存错误检查程序来确保您不尝试访问内存或不在分配的块的边界之外/之外写,尝试读取或基于未初始化的值进行条件跳转,最后,以确认您释放了已分配的所有内存。
对于Linux,$ ./bin/sumdoubles < ../dat/10000float.txt
10000 doubles entered with sum: 117991733.64
是正常选择。每个平台都有类似的内存检查器。它们都很容易使用,只需通过它运行程序即可。
valgrind
始终确认已释放已分配的所有内存,并且没有内存错误。
编辑-功能中的其他问题
在
$ valgrind ./bin/sumdoubles
==6316== Memcheck,a memory error detector
==6316== Copyright (C) 2002-2017,and GNU GPL'd,by Julian Seward et al.
==6316== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6316== Command: ./bin/sumdoubles
==6316==
1.1
2.2
3.3
4.4
5.5
6.6
7.7
8.8
9.9
9 doubles entered with sum: 49.50
==6316==
==6316== HEAP SUMMARY:
==6316== in use at exit: 0 bytes in 0 blocks
==6316== total heap usage: 6 allocs,6 frees,2,288 bytes allocated
==6316==
==6316== All heap blocks were freed -- no leaks are possible
==6316==
==6316== For counts of detected and suppressed errors,rerun with: -v
==6316== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
for(i = 0; i < sizeof(array); i++)
就是sizeof(array)
。数组在访问时转换为指针。请参阅:C11 Standard - 6.3.2.1 Other Operands - Lvalues,arrays,and function designators(p3)。您可能希望同时传递指针和元素数量,例如
sizeof(a_pointer)
您将在double sums(double *array,size_t n)
{
size_t i;
double sumNum = 0;
for(i = 0; i < n; i++){
sumNum = sumNum + array[i];
}
return sumNum;
}
中以{p>的身分呼叫sums
main()
使用size_t sum = sums (arr,used);
函数的示例(经过稍微修改以使其具有品味):
sums
(输出将相同)
仔细检查一下,如果还有其他问题,请告诉我。
本文链接:https://www.f2er.com/3162531.html