-1

I am trying to write a function in C to initialize multiple double type arrays, with different sizes. The array size should be given in the function and the array values are assigned through previously defined functions and values. The functions are to be set as void, since I should use them many times later at different places. Here is a version of the code which does not give reasonable results. Thanks for your help!

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

//interpolation, source code from internet

int findCrossOver(double arr[], int low, int high, double x)
{
  // Base cases
  if (arr[high] <= x) // x is greater than all    
    return high;
  if (arr[low] > x)  // x is smaller than all
    return low;

  // Find the middle point
  int mid = (low + high)/2;  /* low + (high - low)/2 */

  /* If x is same as middle element, then return mid */
  if (arr[mid] <= x && arr[mid+1] > x)
    return mid;

  /* If x is greater than arr[mid], then either arr[mid + 1]
    is ceiling of x or ceiling lies in arr[mid+1...high] */
  if(arr[mid] < x)
      return findCrossOver(arr, mid+1, high, x);

  return findCrossOver(arr, low, mid-1, x);
}

void interp1(double xp[], double yp[], int xyplen, double x[], int xlen,double* y)
{
int index;
int i;
for (i=0; i<xlen; i++)
{
    index = findCrossOver(xp, 0, xyplen-1, x[i]);
    if(x[i] > xp[xyplen-1])
    {
        index--;
    }
    y[i] = ((x[i]-xp[index])*(yp[index+1]-yp[index]))/(xp[index+1]-xp[index]) + yp[index];
}
}

void fpr(double step, double* oldVal, double* xp, double* yp, double* x)
{
   int i;
   int xyplen = 5; //array sizes through many calculations inside the function
   int xylen = 10;  

   for(i=0; i<xyplen; i++)
   {
        xp[i] = i+1;
        yp[i] = 2*xp[i];
        printf("%f\n", xp [i]);
   }
    for (i=0; i<xylen; i++)
    {
        x[i] = i+0.5;
    }
   interp1(xp, yp, xyplen, x, xylen,oldVal);
}


int main()
{
    double *someVal=malloc(sizeof(double));
    double *yp=malloc(sizeof(double));
    double *xp=malloc(sizeof(double));
    double *x=malloc(sizeof(double));
    fpr(1.1,someVal, xp, yp, x); 
    printf("%d\n", sizeof(xp)/sizeof(xp[0]));
    int i;
    printf("Input Data\n");
    for (i=0; i<5; i++)
    {
    printf("(%.1f, %.1f)\t", xp[i], yp[i]);
    }
    printf("Interpolated Data\n");
    for (i=0; i<10; i++)
    {
    printf("(%.1f, %.1f)\t",x[i],someVal[i]);
    }

    return 0;
}

And this is the output (due to the printf commands):

1.000000
2.000000
3.000000
4.000000
5.000000
0
Input Data
(-14.5, 0.5)    (-22.0, -7.0)   (90.5, -14.5)   (653.0, -22.0)  (89.5, 90.5)
Interpolated Data
(90.5, -3.5)    (653.0, -2.5)   (89.5, 0.5) (-9.1, -7.0)    (4.5, -14.5)    (5.5, -22.0)    (6.5, 90.5) (7.5, 653.0)    (8.5, 89.5) (9.5, -9.1) 

As you see the sizeof is just giving the first element address and output in main is not as expected.

1
  • 1
    There must be many duplicates of this, but the short answer is that when you pass an array to a function it decays to a pointer, so when you do sizeof on the function argument you get the size of the pointer and not the array it points to. Not that you have array anyway, you only have pointers to a single value. Commented Jul 27, 2015 at 16:21

2 Answers 2

0

xp and yp are pointers to double in your code, not arrays.

use something like:

double *xp = malloc(sizeof(double) * num_of_elements0);
double *yp = malloc(sizeof(double) * num_of_elements1);

and ALWAYS check for null pointers.

if(xp != NULL && yp != NULL)
{
    /* Your code here */
}

I don't understand how do you want to initialize your arrays. Random numbers? Zeroes?

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

2 Comments

Thanks for your answer. I can't use malloc(sizeof(double) * num_of_elements0) because the num_elements (or the size) is to be defined inside the initialize function. I just need a function which gets many unknown sized arrays and defines their size and elements. I just couldn't figure it out with arrays, so I started using pointers.
Then you could have a look at calloc(). tutorialspoint.com/c_standard_library/c_function_calloc.htm
0

to initialize multiple double type arrays, with different sizes.

There are no arrays in the code you show, but just pointers to memory.

sizeof(xp) returns the size of the pointer xp, always, no matter to how much memory the pointer points.

This line

double *xp=malloc(sizeof(double));

defines xp as pointer to double and intialises it pointing to memory for storing exactly one double.

Same for someVal, yp and x.

By using indexing this memory beyond index 0 the code invokes undefined behaviour.

7 Comments

I tried something like : void fpr(double step, double* oldVal, double* xp, double* yp, double* x) { ..... x=malloc(sizeof(double) * xylen); // interp1(xp, yp, xyplen, x, xylen,oldVal); } with defining double *x; like in the main. although it works when pointers are global
@MRM: On how to allocate an array inside a function you moght like to read here: stackoverflow.com/q/4179273/694576
basically I just want to have local arrays (in main) which are just defined once with the function initialize() and then used in main and other functions. I hope I have said it clearly. And the other thing is I have more than one array to return.
@MDM: Then do the call to malloc(), as you showed in your comment above, in main() and not in fpr(). And do it for each "array" you need, that is allocate as much memory as you need to each of the four pointers.
So there is a confusion here. The problem here is that array sizes are first given inside fpr() and then the array is allocated through that size. This is the idea. My question is, how I can do malloc() without knowing the size in main.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.