-1

The program read a data from a file to an array, load_data loads the data to the array ar. However why do I get a Segmentation fault (core dumped) when I access that array in the main.

#include <stdio.h>
#include <stdlib.h> 
long int load_data(double * ar);

int main(void)
{
    long int n,i;
    double * ar; 
    FILE * fp; 
    double number;

    n=load_data(ar);

    fp = fopen("data-copy.txt","w");
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    for(i=0; i<n; i++)
        fprintf(fp,"%lf\n", ar[i]); //problem here! I can't access!
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    fclose(fp);

    printf("The number of elements in the file is:%ld\n",n);
}

long int load_data(double * ar) 
{
   FILE * fp; 
   double temp;
   long int n=0,i;

   fp = fopen("data.txt","r");
   while(fscanf(fp,"%lf",&temp)==1)
       n++;
   fclose(fp);
   //load memory
   ar = (double*)malloc(sizeof(double)*n);

   fp = fopen("data.txt","r");
   for(i=0; i<n; i++)
   {
       fscanf(fp,"%lf",ar+i);
   //    printf("%lf\n",ar[i]);//This print well!
   }
   fclose(fp);

   return n;
}
an offer can't refuse
  • 4,245
  • 5
  • 30
  • 50
  • 2
    You are passing `ar` by value. So the `ar` in `main` is different then the `ar` in `load_data`. Read [this](http://stackoverflow.com/questions/24052243/why-cant-we-pass-the-pointer-by-reference-in-c). – 001 Sep 09 '15 at 14:41
  • @JohnnyMopp I thought this is very similar to an array. For array I am passing it by address... Thanks, I am going to fix it. – an offer can't refuse Sep 09 '15 at 14:43

2 Answers2

1

All function arguments in C are pass by value.

Your main function copies the value of ar (a garbage value) to wherever the compiler puts function arguments (usually in specified registers or on the stack).

In the function load_data the copy of ar is changed to a pointer to a block of memory but the original ar in main is unchanged and is still garbage.

When you exit the function, you throw away the copy of ar (leaking the malloc block). Then you try to dereference the original ar which is still garbage.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
0

see the program listing below - I have modified your code so that you send the pointer to the pointer ar... this works perfectly now. @Johnny Mopp's comment is perfect.

#include <stdio.h>
#include <stdlib.h> 
long int load_data(double ** ar);

int main(void)
{
    long int n,i;
    double * ar; 
    FILE * fp; 
    double number;

    n=load_data(&ar);

    fp = fopen("data-copy.txt","w");
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    for(i=0; i<n; i++)
        fprintf(fp,"%lf\n", ar[i]); //problem here! I can't access!
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    fclose(fp);

    printf("The number of elements in the file is:%ld\n",n);
}

long int load_data(double ** ar) 
{
   FILE * fp; 
   double temp;
   long int n=0,i;

   fp = fopen("zdata.txt","r");
   while(fscanf(fp,"%lf",&temp)==1)
       n++;
   fclose(fp);
   //load memory
   *ar = (double*)malloc(sizeof(double)*n);

   fp = fopen("zdata.txt","r");
   for(i=0; i<n; i++)
   {
       fscanf(fp,"%lf",*ar+i);
   //    printf("%lf\n",ar[i]);//This print well!
   }
   fclose(fp);

   return n;
}
tom
  • 1,303
  • 10
  • 17