Thread: Matrices in C - subscripted value is neither array nor pointer

  1. #1
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95

    Matrices in C - subscripted value is neither array nor pointer

    Hello, I'm struggling to use matrices in C although I've read so much about pointers and malloc in different literatures. However all my attempts fail, subscripted value is neither array nor pointer being the last.
    What I want to do is have A as global 2D matrix (I know it's just an array) such that functions inside the same source code initialize, modify and print elements of it, by accessing A[i][j] (Java style). I'd read this to be possible, but when I try it doesn't work.
    I also want the size to be allocated at run time.
    Here is my understanding:

    Code:
     
    #include <stdlib.h>
    #include <stdio.h>
    
    int *A; //pointer
    
    .... functions that access A[i][j] , and print. 
    
    int main(int argc, char * argv[]){
    int n = (int) argv[1]; 
    A = malloc(sizeof (int) * n * n); //allocation of memory to the array;
    ....call functions that operate on matrix.
    }
    This doesn't work. Could someone point me out to a solution (preferably giving exact code to achieve the same). I would like to not set an initial size of the array, at the times I declare the global pointer, yet if I had to I'll use realloc(A, n) in the main, but this also doesn't work with me. If you point out how to do that too I'll be grateful.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you need array of pointers

    search forum for two-dimentional dynamic array allocations, should be a lot of samples already. Last time it was discussed not more than 2 weeks ago
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    I did before posting. However when I try to apply the literature found I get compilation (or segmentation/bus errors). Would you help me out with this? I know the literature, the syntax is not working however.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    Let's see:

    Code:
    void read_data(unsigned int rows, const unsigned int cols, double **data)
    {
    	;
    }
    I don't want to be passing the array as input, I want function to operate directly on the global matrix.

    Okay, int **A instead of *A (I had read that int **A is a pointer to pointer *A).
    The malloc I use has only an extra n (shouldn't be a problem if I allocate more memory than I need).
    The loop that initializes the memory location I had not included but had tried it before. Adding it now anyway, I get code that compiles, but at execution I get:
    Bus error

    Further help?

  6. #6
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    any help over here?

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    It's a tad late to be doing this, but I'll take a look at it, now.

  8. #8
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    I've some further inputs. If I 'hide the memory allocation in a function, like this:
    Code:
     
    void allocateMemory(int size){
    	A = malloc(size*sizeof(int));
    	for (i=0; i < size; i++) A[i] = malloc(size*sizeof(*A[i]));
    }
    and the call it from main passing size as a integer value it works. (where int **A is still a global variable). However I'm not yet where I want to be because:
    Cannot I allocate the memory in the main, by placing the above function code (2 lines) directly inside the main instead of wrapping them in a function?
    Most importantly, the size should be passed from the command line as argv[1] (casted) yet when I do that I get a bus error.

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by simpatico_qa View Post
    I've some further inputs. If I 'hide the memory allocation in a function, like this:
    Code:
     
    void allocateMemory(int size){
    	A = malloc(size*sizeof(int));
    	for (i=0; i < size; i++) A[i] = malloc(size*sizeof(*A[i]));
    }
    and the call it from main passing size as a integer value it works. (where int **A is still a global variable). However I'm not yet where I want to be because:
    Cannot I allocate the memory in the main, by placing the above function code (2 lines) directly inside the main instead of wrapping them in a function?
    Most importantly, the size should be passed from the command line as argv[1] (casted) yet when I do that I get a bus error.
    1. the first malloc has wrong size - it should be sizeof(int*) or sizeof *A
    2. show the code where you have bus error - probably problem wwith converting argv[1] to int
    3. check return values of all function calls that cn fail - like malloc
    4. if possible - avoid using global variables
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This doesn't address all your questions, but here's a quick take on it. I added BoyFerrell's posted program, and an example of realloc on a 1D array (all I have on realloc()).

    /*
    This example makes a global array, of undecided size, being declared
    at run time, and subsequently malloc'd. You should add the check for
    success of the malloc call, as you see in the second program example.

    Code:
    */
     
    #include <stdlib.h>
    #include <stdio.h>
    
    
    int **A;
    
    int main()  {
       
       int i, j, k, size;
    
       void printIt(int size);
       printf("\n\n Enter the size for this square array: ");
       scanf("%d", &size);
       i = getchar();
       A = malloc(size * sizeof(int*)); //allocation of memory for the pointers;
    
       for(i = 0; i < size; i++)        //and now for the int's in each col
          A[i] = malloc(size * sizeof(A[0]));
    
       
       printf("\n\n");
       for(i = 0, k = 0; i < size; i++)
          for(j = 0; j < size; j++) {
             A[i][j] = 10 + k;
             k++;
             printf("%d ", A[i][j]);
          }
    
       printIt(size);
       //free the memory
       for(i = 0; i < size; i++)
          free(A[i]);
    
       free(A);
       printf("\n\n\t\t\t program complete, press enter when ready");
       i = getchar();
       return 0;
    }
    void printIt(int size) {
       int i, j;
       printf("\n\n");
       for(i = 0; i < size; i++) {
          for(j = 0; j < size; j++)
             printf("%d ", A[i][j]);
          printf("\n");
       }
    }
    
    
    /* An example of a 2D malloc array (not global) (Vart's linked post 
    of boyferrel's post)
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void read_data(unsigned int rows, const unsigned int cols, double **data)
    {
    	;
    }
    
    int main(void)
    {
          double **data;                       /* 2d array to hold input file values */
          const unsigned long ncols=29;   	   /*  number of columns to read         */
          unsigned long nrows=0;               /*  number of rows in input file      */
    	  unsigned i;
    
          /* allocate data array */
          data = malloc(nrows*sizeof(double*));
          if (data==NULL) 
            {
              printf("Could not allocate data array of size %lu\n",nrows*sizeof(*data));
              return 1;
            }
    
          for (i=0; i<nrows; i++) 
            {
               data[i]=malloc(ncols*sizeof(*data[i]));
                  
    	       if (data[i]==NULL) 
                 {
                    printf("Could not allocate array data[%u] of size %lu\n",i, ncols*sizeof(*data[i]));
                    return 1;
                 }
             }
    
    
          /* read data into data array */
          read_data(nrows, ncols, data);
    
          return 0;
    }
    
    */
    /* This is an example of using realloc(): only example I have.
    
    #include <stdio.h>
    #include <alloc.h>
    #include <string.h>
    
    int main(void)
    {
       char *str;
    
       /* allocate memory for string */
       str = malloc(10);
    
       /* copy "Hello" into string */
       strcpy(str, "Hello");
    
       printf("String is %s\n  Address is %p\n", str, str);
       str = realloc(str, 20);
       printf("String is %s\n  New address is %p\n", str, str);
    
       /* free memory */
       free(str);
    
       return 0;
    }
    */

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  2. [question]Analyzing data in a two-dimensional array
    By burbose in forum C Programming
    Replies: 2
    Last Post: 06-13-2005, 07:31 AM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. Array Program
    By emmx in forum C Programming
    Replies: 3
    Last Post: 08-31-2003, 12:44 AM