0

I have a struct[4] with inside a pointer. I have to malloc this pointer for all the 4 structs

//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).
}

My allocated array is not visible to main. I'm doing something wrong in passing variables, can anyone tell me where?

Thanks

2
  • 2
    The memory from calloc won't be part of the copy. memcpy is a shallow copy. Commented Aug 7, 2019 at 22:59
  • 1
    Don't include "Thanks" in your questions. It is frowned upon here. Commented Aug 7, 2019 at 23:04

5 Answers 5

2

It's not clear what you're trying to copy, but 4 * 10 * sizeof(int) is not correct in any case. You haven't allocated any single contiguous block that size.

If you want to copy just the array of structs, which just copies the pointers to the array, it's:

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

Note that this causes a memory leak, because you never freed the memory that was allocated in b.

If you want to copy each of the arrays of ints, it's

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

This doesn't leak anything, because it's just copying the integers in the arrays, not changing the pointers.

Sign up to request clarification or add additional context in comments.

Comments

1

You're calculating size of a and b incorrectly. a and b are 4-elements array of test_T, each of test_T has a pointer to int array. a and b are not contiguous memory with size 4 * 10 * sizeof(int).

You might need instead:

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

Comments

1

Another easiest way is copy with for() instead of memcpy to avoid confusion,

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

Comments

0

The data structures you have before memcpy() look like this in RAM:

Picture

Each of the rectangles is a continous block of memory. It can be in any place, not necessarily in a special order, and not in adjacent places.

When you do

b[i] = a[i];

then the storage pointed to by b[i] will be "leaked", that means you lose the reference to it and you can't free it. Both b[i] and a[i] will point to the same array of 10 ints.

When you do

memcpy(b, a, sizeof a);

then all storage pointed to by b[0] to b[3] will be leaked.

To copy all ints from a to b, you could use @Barmar's loop, or this one:

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

Comments

0

thank you all for the answers. Maybe I simplified this example too much. Unfortunately, there are many other variables in the structure in question

An example closer to reality can be this:

#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;
}

Copying everything "manually" remains possible but more inconvenient. The strange thing is that I only have the problem if I compile and execute the code with NI CVI. If I compile and execute the code with Eclipse+MinGW I haven't this error

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.