0

sorry I've spent most of today trying to solve what is probably a simple pointer problem, was wondering if anyone could help.

I want a function that returns a number and an array to main(), therefore requiring the use of pointers for at least one of these. The array must be dynamically allocated inside the function.

I've tried to show my best attempt below in a simplified form. I just get "Segmentation Fault".

double my_func(double **ptr);

int main(int argc, char **argv){
  double value;
  double *a;
  value = my_func(&a);

  printf("Value is %f array[1] is %f \n", value, a[1]);
  return 0;
}

double my_func(double **ptr){
  int i;
  /* generate an array */
  void *memory = malloc(10*sizeof(double));

  if (memory == NULL){
    printf("ERROR: out of memory\n");
  }

  *ptr = (double *) memory;


  /* Fill the array with some values */
  for (i=0;i<10;i++)
  {
    **(ptr+i) = 42;
  }


  return 3.14;
}

[The reason for this is that I have a function that reads in a file, and I want to return the number of lines and an array containing the file contents to main(). I want it to dynamically allocate the array, such that the program will operate for any size file.]

Thanks for any help!

1
  • 1
    All three answers were very helpful- thanks all! Commented Mar 24, 2013 at 18:31

3 Answers 3

2

The following line you are adding i to the address of the variable a:

**(ptr+i) = 42;

To add i to the malloced address you need to dereference ptr first:

*(*ptr+i) = 42;
Sign up to request clarification or add additional context in comments.

Comments

0

Besides @ygram's answer, I find it helps to simplify things in the allocating function (my_func in the example) by using an auxiliary variable:

double myfunc(double **a_dp) {
    int i;
    double *dp;

    dp = malloc(10 * sizeof *dp);
    /* no cast required for malloc in C, but make sure you #include <stdlib.h> */

    if (dp == NULL) {
        ... handle error ...
    }

    *a_dp = dp;

    for (i = 0; i < 10; i++)
        dp[i] = 42;

    return 3.14;
}

That is, instead of having to repeatedly write *(*ptr + index) or (*ptr)[index], you create a local variable that holds the value you will also store into *ptr—here I call that local variable dp—and then you just use dp locally, except for the (one, or sometimes a few) places where you must store the value so that your caller receives it.

Comments

0

What is the relationship between the array and the number? For simplicity would it not be better to keep them together in a struct, it would really help to clean things up here.

typedef struct ArrayStruct {
    double num;
    long len; // ideal place to store the array length for future bounds checking!
    double *array;
} ArrayStruct;


int main(int argc, char **argv) {

    ArrayStruct myArray = {0};
    myFunc(&myArray);

    printf("Value is %f array[1] is %f \n", myArray.num, myArray.array[1]);

    free(myArray.array);
    return 0;
}


void myFunc(ArrayStruct *s) {

    // Do whatever you like with the struct:
    s->len = 10;
    s->array = (double *)malloc(s->len * sizeof(double));

    for (int i=0; i< s->len; i++)
        s->array[1] = 42;

    s->num = 3.14;
}

Doing it this way means you don't need to worry about returning anything or messing with pointers, just declare the struct in main, pass a reference to myFunc() or wherever you want to use it, and then alter the data as you see fit.

Sorry if there are any mistakes in that code, just typed it up quickly but it should illustrate the point either way!

Comments

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.