jramm
jramm

Reputation: 6655

Assign array without element by element copy?

I have a function which creates an array, of say, size 5.

Is it possible for the function to accept a pointer (or maybe it needs a pointer to a pointer?) and then point said pointer at an array, so that when the callee then looks at the pointer, it can see all values of the array.

Something along the lines of this (except this will not work):

 #define LENGTH 5
 void assignArray(int *pointer)
 {
       int arr[LENGTH] = {0,1,2,3,4};

       // Point the pointer at the array, without manually copying each element
       pointer = arr;
 }

 void main()
 {
       int *pointer;
       pointer = malloc(sizeof(int) * LENGTH);
       assignArray(pointer);

       int i;
       for (i = 0 ; i < LENGTH ; i++) printf("%d\n", pointer[i]);
 }

Upvotes: 1

Views: 454

Answers (5)

M.M
M.M

Reputation: 141628

The code to do what you are describing might look like:

#define LENGTH 5
void assignArray(int **pp)
{
   static int arr[LENGTH] = {0,1,2,3,4};

   // Point the pointer at the array, without manually copying each element
   *pp = arr;
}

int main()
{
    int *pointer;
    assignArray(&pointer);

    for (int i = 0 ; i < LENGTH ; i++) 
        printf("%d\n", pointer[i]);
}

Note that one does not simply point *pp at a non-static local variable arr. That is because int arr[] = .... would go out of scope when assignArray returns.

If you want each call to assignArray to "return" a different array then of course you will have to allocate space and use memcpy each time you want to make a copy of the original array.

Upvotes: 1

domen
domen

Reputation: 1908

This answer will have two parts:

As mentioned in other answers, this is now how you're supposed to do it. A common construct in similar code is:

void assignArray(int *dest, size_t size)
{
       int i;

       // initialize with some data
       for (i=0; i<size; i++)
               dest[i] = i;
}

This way you're not wasting space and time with an intermediate buffer.


Second part of this answer is about wrapping arrays in a struct. It's a silly trick, that in a way achieves exactly what you asked, and also something that you probably don't want because of extra data copying.

Example code:

#include <stdio.h>
#include <stdlib.h>

#define LENGTH 5
struct foo { int arr[LENGTH]; };

struct foo assignArray()
{
        struct foo bar = { .arr = {0,1,2,3,4} };

        /* return the array wrapper in struct on stack */
        return bar;
}

int main()
{
        struct foo *pointer;
        pointer = malloc(sizeof(*pointer));
        *pointer = assignArray(); /* this will copy the data, not adjust pointer location */

        int i;
        for (i = 0 ; i < LENGTH ; i++) printf("%d\n", pointer->arr[i]);

        return 0;
}

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134366

C assign array without element by element copy

In C, arrays (compile-time allocated) cannot be assigned. You need to copy the elements from one array to another.

To avoid element-by-element copy, you can copy the whole array all at a time using library function.

I'm not very sure what you want to ask here, but it seems, you need to do memcpy() to achieve your goal.

If you have a secondary array arr to copy from, you can write

 memcpy( pointer, arr, ( (sizeof arr[0]) * LENGTH ));

Upvotes: 2

ckruczek
ckruczek

Reputation: 2410

As you are trying to do it, it is not possible due to the fact that your local arr is saved to the stack and is cleaned up after the function assignArry finished. As already mentioned you need to memcpy.

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234795

int arr[LENGTH] = {0,1,2,3,4}; will be stack allocated, so attempting to return the pointer to any of its elements will give you undefined behaviour as the whole thing will be out of scope when the function returns.

If you want to change what a pointer is pointing to then use 2 levels of indirection ** (i.e. pass a pointer to a pointer). You'll need to allocate the array arr on the heap using malloc or something similar.

Upvotes: 0

Related Questions