通常,您需要将FILE *
指针,array
,指向index
的指针和指向当前内存分配max
的指针传递给您的函数。这样你的函数就可以从文件中读取数值到数组中,保持当前索引的数量与当前分配大小进行比较,所以如果值的数量超过当前分配,你可以使用realloc
。最后,通过虚拟使用指针为您index
和你max
分配两者的变化要么是立即回到你的调用函数(通常main()
这些短例子。
把所有的拼在一起,你可以这样做类似的东西来:
/* read array of unknown size int 'a' from 'fp' */
int *readarr (FILE *fp, int *a, size_t *idx, size_t *max)
{
int tmp;
if (!a) /* if a not allocated -- allocate/validate */
if (!(a = calloc (1, *max * sizeof *a))) {
fprintf (stderr, "readarr() virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
while (fscanf (fp, " %d", &tmp) == 1) { /* for each int in file */
if (*idx == *max) { /* check idx and max */
void *ap = realloc (a, 2 * *max * sizeof *a); /* realloc */
if (!ap) { /* validate realloc success */
fprintf (stderr, "realloc() error: memory exhausted.\n");
break; /* if failure, return with exising data */
}
a = ap; /* assign new mem block, zero new mem */
memset (ap + *max * sizeof *a, 0, *max * sizeof *a);
*max *= 2; /* update allocation size */
}
a[(*idx)++] = tmp; /* add int to array, update index */
}
return a; /* return array */
}
(注:功能将接受分配的数组,或NULL
和分配/重新分配按需然而,该值与您的阵列a
不能是静态声明数组因。致电realloc
发生。此外,您必须将函数的返回分配给您的array
,地址为main()
。如果'a'
是NULL
开始用,或者如果realloc
发生,返回新的指针地址。)
归零realloc
后的新内存不是必需的,但它可以帮助防止无意读从一个未初始化的值,如果你稍后使用大于最后存储的值索引的索引迭代数组。
另请注意,当前的重新分配方案每次调用内存时会使内存量增加一倍realloc
。您可以选择尽可能少或根据需要添加。
就这样,一个短的例子把他们放在一起可以是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXI 64
int *readarr (FILE *fp, int *a, size_t *idx, size_t *max);
int main (int argc, char **argv) {
int *array = NULL; /* pointer to array */
size_t i = 0, n = 0, maxi = MAXI; /* index, initial elements */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* valildate file pointer */
fprintf (stderr, "error: file open failed. '%s'\n",
argc > 1 ? argv[1] : "stdin");
return 1;
}
array = readarr (fp, array, &n, &maxi); /* read values from file */
if (fp != stdin) fclose (fp); /* close file */
for (i = 0; i < n; i++) /* print array */
printf (" array[%3zu] : %d\n", i, array[i]);
free (array); /* free memory */
return 0;
}
/* read array of unknown size int 'a' from 'fp' */
int *readarr (FILE *fp, int *a, size_t *idx, size_t *max)
{
int tmp;
if (!a) /* if a not allocated -- allocate/validate */
if (!(a = calloc (1, *max * sizeof *a))) {
fprintf (stderr, "readarr() virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
while (fscanf (fp, " %d", &tmp) == 1) { /* for each int in file */
if (*idx == *max) { /* check idx and max */
void *ap = realloc (a, 2 * *max * sizeof *a); /* realloc */
if (!ap) { /* validate realloc success */
fprintf (stderr, "realloc() error: memory exhausted.\n");
break; /* if failure, return with exising data */
}
a = ap; /* assign new mem block, zero new mem */
memset (ap + *max * sizeof *a, 0, *max * sizeof *a);
*max *= 2; /* update allocation size */
}
a[(*idx)++] = tmp; /* add int to array, update index */
}
return a; /* return array */
}
示例输入100诠释
$ cat dat/100int.txt
27086
29317
32736
...
16892
8270
6444
实施例使用/输出
$ ./bin/fscanf_array_dyn dat/100int.txt
array[ 0] : 27086
array[ 1] : 29317
array[ 2] : 32736
array[ 3] : 3356
...
array[ 97] : 16892
array[ 98] : 8270
array[ 99] : 6444
内存错误检查
在动态分配内存的任何代码你写的,你有关于分配的任何内存块2个responsibilites:(1)总是保留一个指针的起始地址的内存块左右,(2 )当它不再需要时,它可以被释放。
您必须使用内存错误检查程序来确保您没有超出/分配您分配的内存块,尝试读取或基于未初始化值的跳转,并最终确认您已释放所有分配的内存。
对于Linux valgrind
是正常的选择。有很多微妙的方法来滥用新的内存块。使用内存错误检查器可以识别任何问题并验证您分配的内存的正确使用情况,而不是通过segfault
发现问题。每个平台都有类似的内存检查器。它们都很简单,只需通过它运行你的程序。
$ valgrind ./bin/fscanf_array_dyn dat/100int.txt
==7273== Memcheck, a memory error detector
==7273== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7273== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7273== Command: ./bin/fscanf_array_dyn dat/100int.txt
==7273==
array[ 0] : 27086
array[ 1] : 29317
array[ 2] : 32736
...
array[ 97] : 16892
array[ 98] : 8270
array[ 99] : 6444
==7273==
==7273== HEAP SUMMARY:
==7273== in use at exit: 0 bytes in 0 blocks
==7273== total heap usage: 3 allocs, 3 frees, 1,336 bytes allocated
==7273==
==7273== All heap blocks were freed -- no leaks are possible
==7273==
==7273== For counts of detected and suppressed errors, rerun with: -v
==7273== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
务必确认所有堆块被释放 - 无泄漏是可能同样重要错误摘要:0误差为0的上下文。
看看这一切,让我知道你是否还有其他问题。基本的分配和释放内存是C语言的基础。现在最好花时间去完全理解代码,然后最终在桌子上敲打你的头......用你的编码祝你好运。
看起来不错。它工作吗? –
什么让你觉得你做错了什么?它似乎工作得很好。 – Dolda2000
您可能想要获取stat文件中的整数数量。通过这种方式,您可以读取240多个整数的更多/ malloc空间。像'struct stat st; stat(文件名,&st); int numOfIntegers = st.st_size;' – Turtle