Thread: Multidimensional array into function

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    59

    Multidimensional array into function

    I have read a file into an array in my main and it has done so correctly (after help from this board a few threads down). I now need to perform arithmetic with that array in an external function. With the code I have so far it has been successful for all values except array[1][0]. Also, it does not seem to return the final value back into main.

    Let me know if you need to see any more code.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    double finalcalc(double array[][3], int N);
    
    int main()
    {
      FILE* input;
      int N;
      char type[1];
      double array[N][3];
      double *ptr;
      int i, j;
      double finalvalue;
     
      
      input=fopen("filename.xyz", "r");
    
      ptr=malloc(((double)N*3)*sizeof(double));
      i=0;
      for(i=0;i<N;i++)
      {
          fscanf(input, "%s", &type);
          printf("Type %d is %s\n", i, type);
          j=0;
          for(j=0;j<3;j++)
          {
          fscanf(input, "%lf", &array[i][j]);
          printf("array in i = %d and j = %d is %lf\n", i, j, array[i][j]);
          }
       }
      
      fclose(input);
      
      finalvalue=finalcalc(array, N);
      printf("final is %lf\n", finalvalue);
      
      
     
    return 0;
    }
    
    double finalcalc(double array[][3], int N)
    {
      double final;
      double finalvalue;
      int i=0;
      int j=0;
    
      for(i=0;i<N;i++)
      {
        j=0;
        for(j=0;j<3;j++)
        {
          printf("array in i = %d and j = %d is %lf\n", i, j, array[i][j]);
        }
      }
    
      final = 5 * 6; /* The actual mathematics is more complex but left it out for ease */
      printf("Final value is %lf\n", final);
      return(finalvalue);
    }
    edit: Also, would you suggest reading the file into the array using another external function? Should I use global variables for the array and for N (and for final/finalvalue)?
    Last edited by browser; 10-17-2011 at 08:53 AM.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You need to check your compiler settings and insure warnings are being generated. When I compile your code I get these warnings:
    main.c||In function ‘main’:|
    main.c|25|warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘char (*)[1]’|
    main.c||In function ‘finalcalc’:|
    main.c|63|warning: ‘finalvalue’ is used uninitialized in this function|
    main.c||In function ‘main’:|
    main.c|13|warning: ‘N’ is used uninitialized in this function|
    All of these warnings should be considered errors and need to be fixed.

    Jim

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    59
    Thanks Jim, I have fixed those. Still getting the same problem.

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Post your modified code.

    Jim

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    59
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
     
    double finalcalc(double array[][3], int N);
     
    int main()
    {
      FILE* input;
      int N;
      char type;
      double array[N][3];
      double *ptr;
      int i, j;
      double finalvalue;
      
       
      input=fopen("filename.xyz", "r");
     /*NEW BIT THAT I JUST ADDED*/
      fscanf(input, "%d", &N);
      printf("N is %d\n", N); //This gives me 4
    /*END NEW BIT*/
      ptr=malloc(((double)N*3)*sizeof(double));
      i=0;
      for(i=0;i<N;i++)
      {
          fscanf(input, "%s", &type);
          j=0;
          for(j=0;j<3;j++)
          {
          fscanf(input, "%lf", &array[i][j]);
          printf("array in i = %d and j = %d is %lf\n", i, j, array[i][j]);
          }
       }
       
      fclose(input);
      printf("N is still %d\n", N); //This gives me 0
      finalvalue=finalcalc(array, N);
      printf("final is %lf\n", finalvalue);
       
       
      
    return 0;
    }
     
    double finalcalc(double array[][3], int N)
    {
      double final=0;
      double finalvalue=0;
      int i=0;
      int j=0;
     
      for(i=0;i<N;i++)
      {
        j=0;
        for(j=0;j<3;j++)
        {
          printf("array in i = %d and j = %d is %lf\n", i, j, array[i][j]);
        }
      }
     
      final = 5 * 6; /* The actual mathematics is more complex but left it out for ease */
      printf("Final value is %lf\n", final);
      return(finalvalue);
    }
    filename.xyz looks like this
    Code:
        4
    O   -0.906801    0.569837    0.066005
    O    0.956585   -0.258900    0.342064
    O   -0.962633    0.494832    0.380356
    O   -0.259093    0.292540    0.854958
    The problem seems to be in my reading of N. In my first printf it reads perfectly as 4 but it seems to disappear by the second call?

    Thanks

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    In the following snippet:
    Code:
    int main()
    {
      FILE* input;
      int N;
      char type;
      double array[N][3];
    You are using N before it is initialized. Also unless your compiler supports Variable Length Arrays, N must be a constant.

    Jim

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    59
    So if N needs to be read from a file and the array size needs to be set to 3 x N how would I do that without getting this problem?

    Thanks

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You will need to use dynamic memory, malloc/free, after you read the file.

    Jim

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
        int N;
        char type;
        double array[N][3];
    The C99 standard (the "current version" of C) supports variable length arrays, so your declaration of array is gramatically correct, but N is uninitialized at that point. That means array has an unknown dimension, and N may be 0, 1, 4 or 4,000,000. Reading into array may result in undefined behavior if N is too small. You'll be writing to memory you don't own. You need to move the definition of array below where you read N.

  10. #10
    Registered User
    Join Date
    Nov 2009
    Posts
    59
    Jim - I am using malloc after I have read the file...well, while I am reading the file?

    anduril - I moved
    Code:
    double array[N][3];
    double *ptr;
    to above my malloc line. Still prints "N is still 0"

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by browser View Post
    So if N needs to be read from a file and the array size needs to be set to 3 x N how would I do that without getting this problem?
    You can use malloc and a double**, or this is legal under C99 (you may need to set your compiler to accept that):

    Code:
    	int n;
    	scanf("%d", &n);
    
    	double array[n];
    	printf("%lu\n", sizeof(array));
    The issue is that n must be initialized to the proper value before you declare the array.
    Last edited by MK27; 10-17-2011 at 10:54 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Registered User
    Join Date
    Nov 2009
    Posts
    59
    Quote Originally Posted by MK27 View Post
    The issue is that n must be initialized to the proper value before you declare the array.
    Isn't that what I am doing here;
    Code:
    int main()
    {
      FILE* input;
      int N;
      char type;
      int i, j;
      double finalvalue;
       
        
      input=fopen("filename.xyz", "r");
    
      fscanf(input, "%d", &N);
      printf("N is %d\n", N); //This gives me 4 so N now has a value, correct?
      double array[N][3];
      double *ptr;
      ptr=malloc(((double)N*3)*sizeof(double));
      i=0;
      for(i=0;i<N;i++)
      {
          fscanf(input, "%s", &type);
          j=0;
          for(j=0;j<3;j++)
          {
          fscanf(input, "%lf", &array[i][j]);
          printf("array in i = %d and j = %d is %lf\n", i, j, array[i][j]);
          }
       }
        
      fclose(input);
      printf("N is still %d\n", N); //This gives me 0

  13. #13
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    The C99 standard (the "current version" of C) supports variable length arrays
    This is true but not all compilers support C99 or VLA's.

    Jim

  14. #14
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    WARNING a single char can NOT hold a string!!
    You are destroying your own data here.

    Code:
    char type;
    Code:
    fscanf(input, "%s", &type);
    Tim S.

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by browser View Post
    Isn't that what I am doing here;
    Yes. That the value of N would change between those printf lines implies some kind of overwrite. Check it inside the for() loop right before and after the fscanf line here:

    Code:
    int N;
    char type;
    [...]
    fscanf(input, "%s", &type);
    You have read a string into a single char, and a string with content is at minimum two bytes long, including the null terminator. The value of the null terminator is 0, that could be be overwriting the least significant byte of N.

    Also, what the heck is this:

    Code:
    ptr=malloc(((double)N*3)*sizeof(double));
    You don't use it, so I'm not sure what you want there, but whatever it is, that is the wrong way to create it. Maybe you meant:

    Code:
    ptr = (double*)malloc(N*3*sizeof(double));
    Altho the (double*) cast is unnecessary in vanilla C.
    Last edited by MK27; 10-17-2011 at 11:35 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 06-02-2009, 03:07 AM
  2. Passing multidimensional/dynamic array to function
    By epyfathom in forum C Programming
    Replies: 2
    Last Post: 04-02-2009, 05:39 PM
  3. multidimensional array as a function argument
    By Luciferek in forum C++ Programming
    Replies: 7
    Last Post: 09-30-2008, 11:16 AM
  4. Help with passing multidimensional array to function by ref.
    By PatrickSteiger in forum C Programming
    Replies: 2
    Last Post: 11-19-2007, 02:37 PM
  5. multidimensional array function - simple question
    By boltz in forum C++ Programming
    Replies: 6
    Last Post: 05-23-2005, 04:24 PM