Arrays 如何将C中的数组大小加倍
我有一个程序,它以存储在动态数组中的至少10个响应(int)开始,但如果需要,应该使用void函数将大小加倍Arrays 如何将C中的数组大小加倍,arrays,c,dynamic,Arrays,C,Dynamic,我有一个程序,它以存储在动态数组中的至少10个响应(int)开始,但如果需要,应该使用void函数将大小加倍 typedef int* Statistician; int main(int argc, char** argv) { Statistician answer; answer=(int*)calloc(SIZE,sizeof(int)); add(answer, &SIZE); } void add(Statistician answer, int *S
typedef int* Statistician;
int main(int argc, char** argv) {
Statistician answer;
answer=(int*)calloc(SIZE,sizeof(int));
add(answer, &SIZE);
}
void add(Statistician answer, int *SIZE){
answer=(int*)calloc(*SIZE * 2,sizeof(int));
}
这是把它的尺寸扩大一倍的正确方法吗?
我需要朝正确的方向轻轻推一推。最大的误解是您正在按值将
answer
传递给add()
,因此add()
接收一个副本,并且add()
中对answer
的任何更改都会在函数返回时丢失。由于类型为void
,因此您没有机会对调用者中看到的answer
进行更改(main()
此处)
若要解决此问题,请将answer
的地址传递到add()
,以便在realloc()
非calloc()
时对原始指针地址进行操作,使大小加倍,例如
void add(Statistician *answer, int *SIZE){
void *tmp = realloc(*answer, *SIZE * 2 * sizeof **answer);
if (!tmp) {
perror ("add-realloc-answer");
return;
}
*answer = tmp;
/* optional - zero new memory mimicking calloc() */
memset (*answer + *SIZE, 0, *SIZE * sizeof **answer);
*SIZE *= 2;
}
你称之为add,比如:
add(&answer, &SIZE);
(注意,SIZE
必须是一个正确初始化的全局int
。它实际上应该在main()
中替换为SIZE\u t SIZE=SIZE;
,然后将指针传递到SIZE
)
您的困惑更为复杂,因为您将指针定义为类型,请参见。此外,在C中,不需要强制转换malloc
(或calloc
,或realloc
)的返回,这是不必要的。见:
消除指针的typedef
要使指针间接寻址的级别保持明显,更容易避免指针的typedef
,只需在需要类型的地方使用int*
。进行这些更改,并使用局部变量SIZE
更改SIZE
的使用,以确保作为参数传递的任何局部副本不会与全局变量冲突。在考虑add()
之前/之后添加简单例程来填充每个整数并验证每个整数,首选方法是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 128
int *add (int **answer, size_t *size)
{
/* always realloc to a temporary pointer, when realloc fails
* it returns NULL and if you assign to original pointer you
* create a memory leak with loss of your stored data.
*/
void *tmp = realloc(*answer, *size * 2 * sizeof **answer);
if (!tmp) { /* validate every allocation */
perror ("add-realloc-answer");
return NULL;
}
*answer = tmp; /* assign reallocated block to pointer */
/* optional - zero new memory mimicking calloc() */
memset (*answer + *size, 0, *size * sizeof **answer);
*size *= 2; /* update size only on success */
return *answer; /* return pointer indicating success */
}
int main(void) {
int *answer;
size_t size = SIZE;
answer = calloc(size, sizeof *answer); /* allocate */
if (answer == NULL) { /* validate */
perror ("calloc-answer");
return 1;
}
for (size_t i = 0; i < size; i++) /* fill memory */
answer[i] = i;
if (!add(&answer, &size)) /* add and validate return */
fputs ("realloc failed, using original size.\n", stderr);
else
printf ("realloc succeeded -- %zu integers.\n", size);
for (size_t i = size/2; i < size; i++) /* fill new memory */
answer[i] = i;
for (size_t i = 0; i < size; i++) /* validate complete block */
if (i != (size_t)answer[i])
fprintf (stderr, "error: answer[%zu] != %d\n", i, answer[i]);
free (answer); /* free allocated memory */
}
内存使用/错误检查
在您编写的任何动态分配内存的代码中,对于所分配的任何内存块,您有两个责任:(1)始终保留指向内存块起始地址的指针,以便(2)在不再需要它时可以释放它
必须使用内存错误检查程序,以确保您不会试图访问内存或写入超出/超出分配的块的边界,尝试在未初始化的值上读取或基于条件跳转,最后确认释放所有已分配的内存
对于Linux,valgrind
是正常的选择。每个平台都有类似的内存检查器。它们都很容易使用,只需运行程序即可
$ valgrind ./bin/realloc-add
==8594== Memcheck, a memory error detector
==8594== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8594== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8594== Command: ./bin/realloc-add
==8594==
realloc succeeded -- 256 integers.
==8594==
==8594== HEAP SUMMARY:
==8594== in use at exit: 0 bytes in 0 blocks
==8594== total heap usage: 3 allocs, 3 frees, 2,560 bytes allocated
==8594==
==8594== All heap blocks were freed -- no leaks are possible
==8594==
==8594== For counts of detected and suppressed errors, rerun with: -v
==8594== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
始终确认已释放所有已分配的内存,并且没有内存错误
如果您有进一步的问题,请告诉我。重复,并且您正在泄漏内存,请改用
realloc
。@DavidRanieri-不仅泄漏内存,而且当指向包含数据的原始块的原始指针被过度写入时,会丢弃所有原始数据:)
错误的jujujuju。。。
$ valgrind ./bin/realloc-add
==8594== Memcheck, a memory error detector
==8594== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8594== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8594== Command: ./bin/realloc-add
==8594==
realloc succeeded -- 256 integers.
==8594==
==8594== HEAP SUMMARY:
==8594== in use at exit: 0 bytes in 0 blocks
==8594== total heap usage: 3 allocs, 3 frees, 2,560 bytes allocated
==8594==
==8594== All heap blocks were freed -- no leaks are possible
==8594==
==8594== For counts of detected and suppressed errors, rerun with: -v
==8594== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)