Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何将C中的数组大小加倍_Arrays_C_Dynamic - Fatal编程技术网

Arrays 如何将C中的数组大小加倍

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

我有一个程序,它以存储在动态数组中的至少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 *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)