重新分配一维整数数组,保留原始值,将余数清零

时间:2018-10-31 16:29:31

标签: c memcpy realloc calloc memset

我想调整一维整数数组的大小,保留原始数组中的值,并用零初始化新值。到目前为止,我已经提出了两种选择(a)使用callocmemcpy

// Resizes composition
int compo_resize(int len, int *a) {

    // initialise new composition
    int *c = calloc(2*len, sizeof a[0]);

    if (c == NULL) {
        fprintf(stderr, "calloc() failed");
        return LieanderErrorOutOfMemory;
    }

    // copy numbers from old to new composition
    memcpy(c, a, sizeof a[0] * len);

    // modify composition in-place
    *a = *c;

    // release memory
    free(c);

    return LieanderSuccess;
}

和(b)使用reallocmemset

// Resizes composition
int compo_resize(int len, int *a) {

    printf("Note: resizing composition...\n");

    // reallocate memory
    void *c = realloc(a, 2*len);

    if (c == NULL) {
        fprintf(stderr, "realloc() failed");
        return LieanderErrorOutOfMemory;
    }
    else {
        // reassign pointer
        a = c;

        // zero out new elements
        memset(&a[len], 0, len * sizeof a[len]);
    }

    return LieanderSuccess;
}

我想说第二种方法更优雅,更快捷。但是,当集成到较大的程序中时,代码开始返回意外的错误值。我在方法(b)中做错什么了吗?我缺少明显的东西吗?

combo_resize()的调用是int retval = compo_resize(f->len, f->a),其中f是一个自定义结构,称为pair

typedef struct {
    int  fac;  // multiplication factor
    int  idx;  // index of Lieander
    int  len;  // length of compositions
    int  kth;  // no. of elements in compositions
    int *a;    // composition 1
    int *b;    // composition 2
    int  num;  // natural no.
} pair;

3 个答案:

答案 0 :(得分:2)

首先,您需要传递要更新的指针的地址,否则将无法在函数外部修改指针。因为realloc如果找不到足够长的连续区域,可能会改变数据的位置。

第二,请确保您严格限制数组大小与字节大小。

// Resizes composition
int compo_resize(int len, int **a) {

    printf("Note: resizing composition...\n");

    // reallocate memory
    void *c = realloc(*a, sizeof(int) * 2 * len);

    if (c == NULL) {
        fprintf(stderr, "realloc() failed");
        return LieanderErrorOutOfMemory;
    }
    else {
        // reassign pointer
        *a = c;

        // zero out new elements
        memset(&c[len], 0, sizeof(int) * len);
    }

    return LieanderSuccess;
}

答案 1 :(得分:2)

int *a参数需要替换为int **a,因为您要代表调用者更改指针。

// Resizes composition
int compo_resize(int len, int **a) {

    printf("Note: resizing composition...\n");

    // reallocate memory
    int *c = realloc(*a, sizeof(c[0])*2*len);

    if (c == NULL) {
        fprintf(stderr, "realloc() failed");
        return LieanderErrorOutOfMemory;
    }
    else {
        // reassign pointer
        *a = c;

        // zero out new elements
        memset(&c[len], 0, len * sizeof c[len]);
    }

    return LieanderSuccess;
}

答案 2 :(得分:0)

1-不要释放所有带涂层的内存,因为在函数返回后将使用它。

2-将免费的旧* a复制到* c后,考虑使用。

3-从以下位置更改函数声明:

int compo_resize(int len, int *a);

int compo_resize(int len, int **a);

因为要更新指针本身的值以指向新创建的数组。