繁体   English   中英

C,在struct []内部分配一个数组

[英]C, malloc an array inside a struct[]

我有一个带有指针的struct [4]。 我必须为所有4个结构分配此指针

//Here a simplification of my code that produces the same error:

typedef struct{
    int *val;
}test_T;

void testAllocSingle(test_T *in){
    in->val = (int *)calloc(10, sizeof(int));
}

void testAlloc(test_T *in){
    int i = 0;
    for (i=0; i<4; i++){
        testAllocSingle(&(in[i]));
    }
}

void main(void){
    test_T a[4];
    test_T b[4];
    testAlloc(a);
    testAlloc(b);
    memcpy(b, a, 4*10*sizeof(int));
    //FATAL RUN-TIME ERROR: Array argument too small (16 bytes).  Argument    must contain at least 160 bytes (160 elements).
}

我分配的数组对main不可见。 我在传递变量时做错了什么,谁能告诉我在哪里?

谢谢

目前尚不清楚您要复制的内容,但是4 * 10 * sizeof(int)在任何情况下都不正确。 您尚未分配任何单个大小的连续块。

如果您只想复制结构数组,而只是将指针复制到该数组,则为:

memcpy(b, a, 4 * sizeof(test_t));

请注意,这会导致内存泄漏,因为您从未释放过b中分配的内存。

如果您要复制每个int数组,它是

for (int i = 0; i < 4; i++) {
    memcpy(b[i].val, a[i].val, 10 * sizeof(int));
}

这不会泄漏任何内容,因为它只是复制数组中的整数,而不更改指针。

您错误地计算了ab大小。 abtest_T 4元素数组,每个test_T都有一个指向int数组的指针。 ab不是大小为4 * 10 * sizeof(int)连续内存。

您可能需要:

memcpy(b, a, sizeof(a));

另一种最简单的方法是使用for()复制而不是memcpy以避免混淆,

for(i=0;i<4;i++){
b[i] = a[i];
}

在RAM之前, memcpy()之前的数据结构如下所示:

图片

每个矩形都是一个连续的内存块。 它可以在任何地方,不一定是特殊顺序,也可以不在相邻地方。

当你做

b[i] = a[i];

那么b[i]指向的存储将被“泄漏”,这意味着您将丢失对它的引用,并且无法释放它。 b[i]a[i]都将指向10个int s的相同数组。

当你做

memcpy(b, a, sizeof a);

那么b[0]b[3]指向的所有存储将被泄漏。

要将所有inta复制到b ,可以使用@Barmar的循环,也可以使用以下循环:

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 10; j++) {
        b[i].val[j] = a[i].val[j];
    }
}

谢谢大家的回答。 也许我简化了这个例子。 不幸的是,结构中还有许多其他变量

一个更接近现实的例子可以是:

#define    MALLOC_SIZE    (10) //in the original code is a variable
typedef struct{
    int size;
    int x;
    double y;
    char z[32];
    int *val;
}test_T;

void setSize(test_T *in){
    int i = 0;
    for (i=0; i<4; i++){
        in[i].size = 0;
        in[i].size += sizeof(int);//size
        in[i].size += sizeof(int);//x
        in[i].size += sizeof(double);//y
        in[i].size += (sizeof(char)*32);//z
        in[i].size += (sizeof(int)*MALLOC_SIZE);
    }
}

void testAllocSingle(test_T *in){
    in->val = (int *)calloc(MALLOC_SIZE, sizeof(int));
}

void testAlloc(test_T *in){
    int i = 0;
    for (i=0; i<4; i++){
        testAllocSingle(&(in[i]));
    }
}

int main(void){
    int tot_size = 0;

    test_T a[4];
    test_T b[4];

    testAlloc(a);
    testAlloc(b);

    setSize(a);
    tot_size = a[0].size + a[1].size + a[2].size + a[3].size;

    memcpy(b, a, tot_size);
    //FATAL RUN-TIME ERROR: Array argument too small (16 bytes).  Argument    must contain at least 160 bytes (160 elements).
    return 0;
}

仍然可以“手动”复制所有内容,但更为不便。 奇怪的是,只有使用NI CVI编译并执行代码时,我才有问题。 如果我使用Eclipse + MinGW编译并执行代码,则不会出现此错误

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM