Pass data from a C function via double pointer in Cython - c

I want to use a small C routine with Cython. The C function itself is
#include <stdio.h>
#include "examples.h"
void add_array(int **io_array, int n) {
int i;
int *array;
array = (int *) malloc(n * sizeof(int));
for(i = 0; i < n; i++) {
array[i] = i;
}
*io_array = array;
}
And the function prototype:
#ifndef EXAMPLES_H
#define EXAMPLES_H
void add_array(int **io_array, int n);
#endif
Now I want to use Cython to interface the C function with:
cdef extern from "examples.h":
void add_array(int **io_array, int n)
import numpy as np
def add(arr):
if not arr.flags['C_CONTIGUOUS']:
arr = np.ascontiguousarray(arr, dtype=np.int32)
cdef int[::1] arr_memview = arr
add_array(&arr_memview[0], arr_memview.shape[0])
return arr
When compiling it gives the error:
pyexamples.pyx:13:14: Cannot assign type 'int *' to 'int **'
What is the right way to interface this function?

It will not work out-of-the-box with numpy-arrays. You will have to make the memory management yourself, for example:
%%cython
from libc.stdlib cimport free
def doit():
cdef int *ptr;
add_array(&ptr, 5)
print(ptr[4])
free(ptr) #memory management
The difference to your attempt: &arr_memview[0] is pointer to an integer array, but what you need for your function is a pointer to a pointer to an integer array - that is what &ptr is.
The problem with your function is, that it has too many responsibilities:
it allocates the memory
it initializes the memory
It would be easier, if add_array would only be doing the second part, i.e.
void add_array(int *io_array, int n) {
int i;
for(i = 0; i < n; i++) {
io_array[i] = i;
}
}
And thus any memory could be initialized (also memory which was not allocated with malloc).
However, it is possible to create a numpy-array using the returned pointer ptr, it is just less straight forward:
cimport numpy as np
import numpy as np
np.import_array() # needed to initialize numpy-data structures
cdef extern from "numpy/arrayobject.h":
void PyArray_ENABLEFLAGS(np.ndarray arr, int flags) #not include in the Cython default include
def doit():
cdef int *ptr;
add_array(&ptr, 5)
# create numpy-array from data:
cdef np.npy_intp dim = 5
cdef np.ndarray[np.int32_t, ndim=1] arr = np.PyArray_SimpleNewFromData(1, &dim, np.NPY_INT32, ptr)
# transfer ownership of the data to the numpy array:
PyArray_ENABLEFLAGS(arr, np.NPY_OWNDATA)
return arr
The following is worth mentioning:
np.import_array() is needed to be able to use all of the numpy's functionality. Here is an example of what can happen, if np.import_array() isn't called.
After PyArray_SimpleNewFromData, the data itself isn't owned by the resulting numpy array, thus we need to enable the OWNDATA-flag, otherwise there will be a memory leak.
It is not obvious, that the resulting numpy-array can be responsible for freeing the data. For example instead of using malloc/free it could be using Python's memory allocator.
I would like to elaborate about point 3. above. Numpy uses a special function to allocate/deallocate memory for data - it is PyDataMem_FREE and uses system's free for it. So in your case (using system's malloc/free in add_array) everything is Ok. (PyDataMem_FREE should not be confused with PyArray_free, as I did in an earlier version of the answer. PyArray_free is responsible for freeing other elements (array itself, and dimension/strides data, not data-memory) of the numpy-array, see here and is different depending on Python version).
A more flexible/safe approach is to use PyArray_SetBaseObject as shown in this SO-post.

Related

Passing a 2D array to a function in C?

I need to pass a 2D array to a function.
#include <stdio.h>
#define DIMENSION1 (2)
#define DIMENSION2 (3)
void func(float *name[])
{
for( int i=0;i<DIMENSION1;i++){
for( int j=0;j<DIMENSION2;j++){
float element = name[i][j];
printf("name[%d][%d] = %.1f \n", i, j, element);
}
}
}
int main(int argc, char *argv[])
{
float input_array[DIMENSION1][DIMENSION2] =
{
{0.0f, 0.1f, 0.2f},
{1.0f, 1.1f, 1.2f}
};
func(input_array);
return 0;
}
Dimensions vary depending on the use case, and the func should stay the same.
I tried the above int func(float *[]) but compiler complains expected ‘float **’ but argument is of type ‘float (*)[3]’, and also I get the segmentation fault error at runtime when trying to access the array at element = name[i][j].
What would be the proper signature of my function? Or do I need to call the func differently?
You can use the following function prototype:
int func(int dim1, int dim2, float array[dim1][dim2]);
For this you have to pass both dimensions to the function (you need this values anyhow in the function). In your case it can be called with
func(DIMENSION1, DIMENSION2, input_array);
To improve the usability of the function call, you can use the following macro:
#define FUNC_CALL_WITH_ARRAY(array) func(sizeof(array)/sizeof(*(array)), sizeof(*(array))/sizeof(**(array)), array)
Then you can call the function and it will determine the dimensions itself:
FUNC_CALL_WITH_ARRAY(input_array);
Full example:
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#define FUNC_CALL_WITH_ARRAY(array) func(sizeof(array)/sizeof(*(array)), sizeof(*(array))/sizeof(**(array)), array)
int func(int dim1, int dim2, float array[dim1][dim2])
{
printf("dim1 %d, dim2 %d\n", dim1, dim2);
return 0;
}
#define DIMENSION1 (4)
#define DIMENSION2 (512)
int main(int argc, char *argv[])
{
float input_array[DIMENSION1][DIMENSION2];
FUNC_CALL_WITH_ARRAY(input_array);
float input_array2[7][16];
FUNC_CALL_WITH_ARRAY(input_array2);
}
Will print
dim1 4, dim2 512
dim1 7, dim2 16
Dimensions vary depending on the use case, and the func should stay the same.
Use VLA:
void func (int r, int c, float arr[r][c]) {
//access it like this
for (int i = 0; i < r; ++i) {
for (int j = 0; j < c; ++j) {
printf ("%f\n", arr[i][j]);
}
}
}
// call it like this
func (DIMENSION1, DIMENSION2, input_array);
You can change your function like this;
int func(float (*arr)[DIMENSION2])
{
}
But also you should change your main code like this;
float input[DIMENSION1][DIMENSION2];//I just upload the dimension1 to dimension2
As noted above in the comment, the key problem is that int func(float *name[]) declares name to be an array of pointers to float.
In this sense, the following modification to main() works:
int main(int argc, char *argv[])
{
float input_array[DIMENSION1][DIMENSION2] =
{
{0.0f, 0.1f, 0.2f},
{1.0f, 1.1f, 1.2f}
};
/* Declare an array of pointers, as this is what func requires at input: */
float* in_p[DIMENSION1];
/* ... and initialize this array to point to first elements of input array: */
for( int i=0;i<DIMENSION1;i++)
in_p[i] = input_array[i];
/* ... and send this array of pointers to func: */
func(in_p);
return 0;
}
This is going to present a very old solution, one that works on every C compiler that exists. The idea goes something like this:
I have multiple pieces of information to keep track of
I should keep them together
This leads us to the idea that we can use a composite type to hold all the related information in one place and then treat that object as a single entity in our code.
There is one more pebble in our bowl of sand:
the size of the information varies
Whenever we have varying-sized objects, dynamic memory tends to get involved.
Arrays vs Pointers
C has a way of losing information when you pass an array around. For example, if you declare a function like:
void f( int a[] )
it means exactly the same thing as:
void f( int * a )
C does not care that the size of the array is lost. You now have a pointer. So what do we do? We pass the size of the array also:
void f( int * a, size_t n )
C99 says “I can make this prettier, and keep the array size information, not just decay to a pointer”. Okay then:
void f( size_t dim1, size_t dim2, float array[dim1][dim2] )
We can see that it is pretty, but we still have to pass around the array’s dimensions!
This is reasonable, as the compiler needs to make the function work for any array, and array size information is kept by the compiler, never by executable code.
The other answers here either ignore this point or (helpfully?) suggest you play around with macros — macros that only work on an array object, not a pointer.
This is not an inherently bad thing, but it is a tricky gotcha: you can hide the fact that you are still individually handling multiple pieces of information about a single object,
except now you have to remember whether or not that information is available in the current context.
I consider this more grievous than doing all the hard stuff once, in one spot.
Instead of trying to juggle all that, we will instead use dynamic memory (we are messing with dynamic-size arrays anyway, right?)
to create an object that we can pass around just like we would with any other array.
The old solution presented here is called “the C struct hack”. It is improved in C99 and called “the flexible array member”.
The C struct hack has always worked with all known compilers just fine, even though it is technically undefined behavior.
The UB problem comes in two parts:
writing past the end of any array is unchecked, and therefore dangerous, because the compiler cannot guarantee you aren’t doing something stupid outside of its control
potential memory alignment issues
Neither of these are an actual issue. The ‘hack’ has existed since the beginning (much to Richie’s reported chagrin, IIRC), and is now codified (and renamed) in C99.
How does this magic work, you ask?
Wrap it all up in a struct:
struct array2D
{
int rows, columns;
float values[]; // <-- this is the C99 "flexible array member"
};
typedef struct array2D array2D;
This struct is designed to be dynamically-allocated with the required size. The more memory we allocate, the larger the values member array is.
Let’s write a function to allocate and initialize it properly:
array2D * create2D( int rows, int columns )
{
array2D * result = calloc( sizeof(array2D) + sizeof(float) * rows * columns, 1 ); // The one and only hard part
if (result)
{
result->rows = rows;
result->columns = columns;
}
return result;
}
Now we can create a dynamic array object, one that knows its own size, to pass around:
array2D * myarray = create2D( 3, 4 );
printf( "my array has %d rows and %d columns.\n", myarray->rows, myarray->columns );
free( myarray ); // don’t forget to clean up when we’re done with it
The only thing left is the ability to access the array as if it were two-dimensional.
The following function returns a pointer to the desired element:
float * index2D( array2D * a, int row, int column )
{
return a->values + row * a->columns + column; // == &(a->values[row][column])
}
Using it is easy, if not quite as pretty as the standard array notation.
But we are messing with a compound object here, not a simple array, and it goes with the territory.
*index2D( myarray, 1, 3 ) = M_PI; // == myarray[ 1 ][ 3 ] = M_PI
If you find that intolerable, you can use the suggested variation:
float * getRow2D( array2D * a, int row )
{
return a->values + row * a->columns; // == a->values[row]
}
This will get you “a row”, which you can array-index with the usual syntax:
getRow2D( myarray, 1 )[ 3 ] = M_PI; // == myarray[ 1 ][ 3 ] = M_PI
You can use either if you wish to pass a row of your array to a function expecting only a 1D array of floats:
void some_function( float * xs, int n );
some_function( index2D( myarray, 1, 0 ), myarray->columns );
some_function( getRow2D( myarray, 1 ), myarray->columns );
At this point you have already seen how easy it is to pass our dynamic 2D array type around:
void make_identity_matrix( array2D * M )
{
for (int row = 0; row < M->rows; row += 1)
for (int col = 0; col < M->columns; col += 1)
{
if (row == col)
*index2D( M, row, col ) = 1.0;
else
*index2D( M, row, col ) = 0.0;
}
}
Shallow vs Deep
As with any array in C, passing it around really only passes a reference (via the pointer to the array, or in our case, via the pointer to the array2D struct).
Anything you do to the array in a function modifies the source array.
If you want a true “deep” copy of the array, and not just a reference to it, you still have to do it the hard way.
You can (and should) write a function to help.
This is no different than you would have to do with any other array in C, no matter how you declare or obtain it.
array2D * copy2D( array2D * source )
{
array2D * result = create2D( source->rows, source->columns );
if (result)
{
for (int row = 0; row < source->rows; row += 1)
for (int col = 0; col < source->cols; col += 1)
*index2D( result, row, col ) = *index2D( source, row, col );
}
return result;
}
Honestly, that nested for loop could be replaced with a memcpy(), but you would have to do the hard stuff again and calculate the array size:
array2D * copy2D( array2D * source )
{
array2D * result = create2D( source->rows, source->columns );
if (result)
{
memcpy( result->values, source->values, sizeof(float) * source->rows * source->columns );
}
return result;
}
And you would have to free() the deep copy, just as you would any other array2D that you create.
This works the same as any other dynamically-allocated resource, array or not, in C:
array2D * a = create2D( 3, 4 ); // 'a' is a NEW array
array2D * b = copy2D( a ); // 'b' is a NEW array (copied from 'a')
array2D * c = a; // 'c' is an alias for 'a', not a copy
...
free( b ); // done with 'b'
free( a ); // done with 'a', also known as 'c'
That c reference thing is exactly how pointer and array arguments to functions work in C, so this should not be something surprising or new.
void myfunc( array2D * a ) // 'a' is an alias, not a copy
Hopefully you can see how easy it is to handle complex objects like variable-size arrays that keep their own size in C, with only a minor amount of work in one or two spots to manage such an object. This idea is called encapsulation (though without the data hiding aspect), and is one of the fundamental concepts behind OOP (and C++). Just because we’re using C doesn’t mean we can’t apply some of these concepts!
Finally, if you find the VLAs used in other answers to be more palatable or, more importantly, more correct or useful for your problem, then use them instead! In the end, what matters is that you find a solution that works and that satisfies your requirements.

Warning: Return from incompatible pointer type

The code below is producing a compiler warning: return from incompatible pointer type. The type I'm returning seems to be the issue but I cant seem to fix this warning.
I have tried changing the type of hands to int *. Also have tried returning &hands.
int * dealDeck(int numPlayers, int numCards, int cardDeck[])
{
static int hands[MAX_PLAYERS][MAX_CARDS]={0};
int start = 0;
int end = numCards;
int player, hand, j;
int card;
for(player = 0; player < numPlayers; player++)
{
for(hand = start, j=0; hand < end; hand++,j++)
{
card = cardDeck[hand];
hands[player][j] = card;
}
start = end;
end += numCards;
}
return hands;
}
This function should return a pointer to the array "hands". This array is then passed to another function which will print out its elements.
The hands variable is not an int * this is a int **
So you need to return a int **
This is a 2d array.
First of all, you have declared return type of int *, which would mean, that you are trying to return an array, while you want to return a 2-dimensional array. The proper type for this would usually be int **, but that won't cut it here. You opted to go with static, fixed size array. That means, that you need to return pointer to some structures of size MAX_CARDS * sizeof(int) (and proper type, which is the real problem here). AFAIK, there is no way to specify that return type in C*.
There are many alternatives though. You could keep the static approach, if you specify only up to 1 size (static int *hands[MAX_PLAYERS] or static int **hands), but then you need to dynamically allocate the inner arrays.
The sane way to do it is usually "call by reference", where you define the array normally before calling the function and you pass it as a parameter to the function. The function then directly modifies the outside variables. While it will help massively, with the maintainability of your code, I was surprised to find out, that it doesn't get rid of the warning. That means, that the best solution is probably to dynamically allocate the array, before calling the function and then pass it as an argument to the function, so it can access it. This also solves the question of whether the array needs to be initialized, and whether = {0} is well readable way to do it (for multidimensional array) , since you'll have to initialize it "manually".
Example:
#include <stdio.h>
#include <stdlib.h>
#define PLAYERS 10
#define DECKS 20
void foo(int **bar)
{
bar[0][0] = 777;
printf("%d", bar[0][0]);
/*
* no point in returning the array you were already given
* but for the purposes of curiosity you could change the type from
* void to int ** and "return bar;"
*/
}
int main()
{
int **arr;
arr = malloc(sizeof(int *) * PLAYERS);
for (size_t d = 0; d < DECKS; d++) {
/* calloc() here if you need the zero initialization */
arr[d] = malloc(sizeof(int) * DECKS);
}
foo(arr);
return 0;
}
*some compilers call such type like int (*)[20], but that isn't valid C syntax

How to return multiple types from a function in C?

I have a function in C which calculates the mean of an array. Within the same loop, I am creating an array of t values. My current function returns the mean value. How can I modify this to return the t array also?
/* function returning the mean of an array */
double getMean(int arr[], int size) {
int i;
printf("\n");
float mean;
double sum = 0;
float t[size];/* this is static allocation */
for (i = 0; i < size; ++i) {
sum += arr[i];
t[i] = 10.5*(i) / (128.0 - 1.0);
//printf("%f\n",t[i]);
}
mean = sum/size;
return mean;
}
Thoughts:
Do I need to define a struct within the function? Does this work for type scalar and type array? Is there a cleaner way of doing this?
You can return only 1 object in a C function. So, if you can't choose, you'll have to make a structure to return your 2 values, something like :
typedef struct X{
double mean;
double *newArray;
} X;
BUT, in your case, you'll also need to dynamically allocate the t by using malloc otherwise, the returned array will be lost in stack.
Another way, would be to let the caller allocate the new array, and pass it to you as a pointer, this way, you will still return only the mean, and fill the given array with your computed values.
The most common approach for something like this is letting the caller provide storage for the values you want to return. You could just make t another parameter to your function for that:
double getMean(double *t, const int *arr, size_t size) {
double sum = 0;
for (size_t i = 0; i < size; ++i) {
sum += arr[i];
t[i] = 10.5*(i) / (128.0 - 1.0);
}
return sum/size;
}
This snippet also improves on some other aspects:
Don't use float, especially not when you intend to return a double. float has very poor precision
Use size_t for object sizes. While int often works, size_t is guaranteed to hold any possible object size and is the safe choice
Don't mix output in functions calculating something (just a stylistic advice)
Declare variables close to where they are used first (another stylistic advice)
This is somewhat opinionated, but I changed your signature to make it explicit the function is passed pointers to arrays, not arrays. It's impossible to pass an array in C, therefore a parameter with an array type is automatically adjusted to the corresponding pointer type anyways.
As you don't intend to modify what arr points to, make it explicit by adding a const. This helps for example the compiler to catch errors if you accidentally attempt to modify this array.
You would call this code e.g. like this:
int numbers[] = {1, 2, 3, 4, 5};
double foo[5];
double mean = getMean(foo, numbers, 5);
instead of the magic number 5, you could write e.g. sizeof numbers / sizeof *numbers.
Another approach is to dynamically allocate the array with malloc() inside your function, but this requires the caller to free() it later. Which approach is more suitable depends on the rest of your program.
Following the advice suggested by #FelixPalmen is probably the best choice. But, if there is a maximum array size that can be expected, it is also possible to wrap arrays in a struct, without needing dynamic allocation. This allows code to create new structs without the need for deallocation.
A mean_array structure can be created in the get_mean() function, assigned the correct values, and returned to the calling function. The calling function only needs to provide a mean_array structure to receive the returned value.
#include <stdio.h>
#include <assert.h>
#define MAX_ARR 100
struct mean_array {
double mean;
double array[MAX_ARR];
size_t num_elems;
};
struct mean_array get_mean(int arr[], size_t arr_sz);
int main(void)
{
int my_arr[] = { 1, 2, 3, 4, 5 };
struct mean_array result = get_mean(my_arr, sizeof my_arr / sizeof *my_arr);
printf("mean: %f\n", result.mean);
for (size_t i = 0; i < result.num_elems; i++) {
printf("%8.5f", result.array[i]);
}
putchar('\n');
return 0;
}
struct mean_array get_mean(int arr[], size_t arr_sz)
{
assert(arr_sz <= MAX_ARR);
struct mean_array res = { .num_elems = arr_sz };
double sum = 0;
for (size_t i = 0; i < arr_sz; i++) {
sum += arr[i];
res.array[i] = 10.5 * i / (128.0 - 1.0);
}
res.mean = sum / arr_sz;
return res;
}
Program output:
mean: 3.000000
0.00000 0.08268 0.16535 0.24803 0.33071
In answer to a couple of questions asked by OP in the comments:
size_t is the correct type to use for array indices, since it is guaranteed to be able to hold any array index. You can often get away with int instead; be careful with this, though, since accessing, or even forming a pointer to, the location one before the first element of an array leads to undefined behavior. In general, array indices should be non-negative. Further, size_t may be a wider type than int in some implementations; size_t is guaranteed to hold any array index, but there is no such guarantee for int.
Concerning the for loop syntax used here, e.g., for (size_t i = 0; i < sz; i++) {}: here i is declared with loop scope. That is, the lifetime of i ends when the loop body is exited. This has been possible since C99. It is good practice to limit variable scopes when possible. I default to this so that I must actively choose to make loop variables available outside of loop bodies.
If the loop-scoped variables or size_t types are causing compilation errors, I suspect that you may be compiling in C89 mode. Both of these features were introduced in C99.If you are using gcc, older versions (for example, gcc 4.x, I believe) default to C89. You can compile with gcc -std=c99 or gcc -std=c11 to use a more recent language standard. I would recommend at least enabling warnings with: gcc -std=c99 -Wall -Wextra to catch many problems at compilation time. If you are working in Windows, you may also have similar difficulties. As I understand it, MSVC is C89 compliant, but has limited support for later C language standards.

Load Structs in C

In my header file I have defined some structs:
typedef struct { double X; } feature_t;
typedef struct
{
int n;
feature_t *Features;
float *Weights;
} signature_t;
In my main code I declare some new structs and try to load them:
feature_t *f_x;
int i;
memset(f_x,0,sizeof(feature_t)*n_x);
for(i=0; i<n_x; i++){
f_x[i] = 100.0;
w_x[i] = (float)p_x[i];
}
When I go to compile this, I get the following error:
error: incompatible types when assigning to type ‘feature_t {aka struct <anonymous>}’ from type ‘double’
Why does the compiler having trouble loading this double into this field? I declared it as a double.
thanks!
There is a compile problem and a run-time problem that needs to be fixed once the compile problem is out of the way.
The compile problem is that you cannot cast a float to a struct, even when the struct's only field is a float. You need to assign it like this:
f_x[i].X = ... // some float expression here
The run-time problem is that feature_t *f_x; pointer cannot be used like an array until you assign it some memory. Recall that pointers are not arrays. You need to do something like this:
feature_t *f_x = malloc(sizeof(*f_x)*n_x);
You have two options:
The first: make your feature_t instance an "automatic" variable on the stack - so no extra work needs to be done, but you can't use the object from the caller of the function that creates it:
void doSomething(size_t n) {
struct feature_t f_x[n];
for(size_t i = 0; i < n; i++) {
f_x[i] = {};
f_x[i].X = 100.0;
}
}
(Note the above example uses a VLA, this is not permitted in C++, only C99)
Because f_X lives in the stack, the = {} initialization syntax means the raw object data in the stack is zeroed out.
(Note that you cannot use the ={} syntax to initialize a VLA, each element must be initialized individually)
The second is to use the heap, but you must ensure you deallocate the memory eventually otherwise it will be a memory leak:
void doSomething(size_t n) {
struct feature_t* f_x = calloc( n, sizeof(struct feature_t) );
if( f_x == NULL ) exit( EXIT_FAILURE );
for(size_t i = 0; i < n; i++) {
f_x[i].X = 100.0;
}
free( f_x );
}
In this case, f_x is actually a pointer to the array of feature_t instances that lives on the heap, so its lifespan is potentially beyond the doSomething function scope - however I called free before the function returned.
I used calloc which allocates and zeroes-out memory before returning control to the caller, whereas malloc only allocates memory and exposes what memory contents were there previously, which is generally undesirable unless you absolutely need the performance gains by not explicitly zeroing memory.

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:
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!
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);
}
Dynamic size arrays are not allowed in older c versions, so you can either:
change compilation flags to suit you and allow you to compile, if you are using an IDE this can be IDE dependent.
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
}
}
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.
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];
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
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];
}
}

Resources