space_voyager
space_voyager

Reputation: 2034

How to use only part of an input array to a function?

I am required to pass a constant-size array to a function in C, but only use part of that array. Specifically, the following pseudo-code explains my situation:

void my_function(int arr_end,double arr[20]) {
    Create new array arr_new that contains elements 0 to arr_end or arr
    Use arr_new
}

So far, I tried to do the following:

void my_function(int arr_end,double arr[20]) {
    double arr_new[arr_end+1];
    int i;
    for(i=0;i<=arr_end;i++){
       arr_new[i] = arr[i];
    }
    // Now I can do what I want with arr_new
}

But I get the error: int arr_end expression must have a constant value . Here's a screenshot of the error in Visual Studio Community 2015: enter image description here

My problem is that arr_end is not constant (it means that at different times I want to extract a different portion of arr).

How can I achieve what I want (make arr_new contain a part of arr) using only for basic code and without malloc or anything like this? Thanks!

Upvotes: 1

Views: 1931

Answers (5)

monkeyStix
monkeyStix

Reputation: 630

Dynamic size arrays are not allowed in older c versions, so you can either:

  1. change compilation flags to suit you and allow you to compile, if you are using an IDE this can be IDE dependent.

  2. allocate the array dynamically using malloc or a similar function like so:

void my_function(int arr_end,double arr[20])
{
    double *arr_new = malloc((arr_end+1) * sizeof(arr[0]));
    int i;
    for(i=0;i<=arr_end;i++){
       // do whatever you need
    }
}
  1. allocate an array of size 20 on the stack and just use only part of it(using the for loop) like so:
void my_function(int arr_end,double arr[20]) {
    double arr_new[20];
    int i;
    for(i=0;i<=arr_end;i++){
       //do whatever you need
    }
}

if you must send only the parts you need, method 2 is preferable.

Upvotes: 1

Jean Pierre Dudey
Jean Pierre Dudey

Reputation: 665

First in the my_function arguments you are declaring that you are receiving an array with a size of 20 (double arr[20]), since arrays cannot be passed by value it gets converted to double* arr (see this) without knowing how many elements arr has, so you should be carefully or you will get a segfault. A recommended approach would be to change double arr[20] to double* arr and add another argument for the size of arr. Example:

void my_function(const size_t arr_end, double* arr, const size_t arr_size) {
    ...
}

Second you are trying to use VLAs with MSVC which only supports C90 and VLAs we're added on C99 so you will need to allocate memory manually with malloc and free it with free when you finished using it.

Now here is the code fixed:

void my_function(size_t arr_end, double* arr, size_t arr_size) {
    double* arr_new = NULL;

    // Allocate enough memory to hold the array
    arr_new = malloc((arr_end + 1) * sizeof(double));

    // Copy arr elements to arr_new
    for(int i = 0; i <= arr_end; i++){
       arr_new[i] = arr[i];
    }

    // Now you can do what you want with arr_new

    // When you finished using it.
    free(arr_new);
}

Upvotes: 1

user3450456
user3450456

Reputation: 25

Use dynamic allocation. Code:

void foo(int end, double arr[20]){
    double* newArr = malloc((end + 1) * sizeof(double));
    //now you can use newArr like a normal array
    //Copy like this
    for(int i = 0; i < end; i++){
        newArr[i] = arr[i];
    }
}

Upvotes: 0

Magnus
Magnus

Reputation: 59

Apparently, the problem lies with Visual Studio. The concept of Variable Length Arrays (VLAs) is of the C99 standard, whereas Visual Studio seems to support only C90.

They do seem have a workaround for that however, you can find it here: https://msdn.microsoft.com/en-us/library/zb1574zs(v=vs.140).aspx

Upvotes: 0

henrybbosa
henrybbosa

Reputation: 1125

As far as I know the problem is that when you are creating dynamic arrays then the only way is using malloc to allocate space. Then you assign it to an array as in double arr_new[arr_end+1];. arr_end can only be an explicit value, e.g., 1, 2, or 3, not a variable like arr_end. It should be something like this double arr_new[5];

Upvotes: 0

Related Questions