Thread: 2D Array of int ADT - debugging help please!

  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    2

    2D Array of int ADT - debugging help please!

    Hello,

    I've written a C Library to deal with 2D arrays of integers. However I keep getting segmentation errors when I try to use the setArray() or getArray() function, and I'm not sure why. Probably trying to use memory I haven't allocated? Any help would be muchos appreciated.

    The code can be viewed at http://www.bath.ac.uk/~jah29/CM10138/ if you find that easier.

    2DArray.h
    Code:
    #ifndef ARRAY_H
    #define ARRAY_H
    
    extern int **createArray(int x, int y);
    extern int setArray(int **array, int x, int y, int value);
    extern int getArray(int **array, int x, int y);
    #endif
    2DArray.c
    Code:
    #include "2DArray.h"
    
    static int max_x;
    
    static int max_y;
    
    /* allocates memory for a new array of chosen size */
    int **createArray(int x, int y)
    {
      int **array;
      int i = 0;
      max_x = x;
      max_y = y;
      array = malloc(max_x * sizeof(int *));
      for(i = 0; i < max_x; i++)
      {
        array[i] = malloc(max_y * sizeof(int));
      }
      return &array[0];
    }
    
    /* sets the value of a 'cell' in the 2d array,
    ** returns 0 if successfull, 1 otherwise
    */
    int setArray(int **array, int x, int y, int value)
    {
      if(x > 0 && x < max_x && y > 0 && y < max_y)
      {
        array[x][y] = value;
        return 0;
      }
      else
      {
         return 1;
      }
    }
    
    /* returns the value at specified 'cell', returns 0 if out of bounds */
    int getArray(int **array, int x, int y)
    {
      if(x > 0 && x < max_x && y > 0 && y < max_y)
      {
        return (int)array[x][y];
      }
      else
      {
        return 0;
      }
    }
    arraytest.c
    Code:
    /* ArrayTest.c */
    
    #include <stdio.h>
    #include "2DArray.h"
    
    main()
    {
      int temp;
      int **array1;
      int **array2;
    
      array1 = **createArray(10, 5);
      printf("Array 10 by 5 created\n");
      
      array2 = **createArray(15, 3);
      printf("Array 15 by 3 created\n");
    
      setArray(array1, 5, 3, 100);
      /*if (temp != 0)
      {
        printf("Error array1\n");
      }
      else
      {
        printf("Integer set array1\n");
      }*/
      
      temp = getArray(array1, 5, 3);
      if(temp != 0)
        printf("%d at array1 (5, 3)\n", temp);
      else
        printf("Nothing stored at array1 (5, 3) yet!\n");
        
      setArray(array2, 10, 1, 256);
      temp = getArray(array2, 10, 1);
      if(temp != 0)
        printf("%d at array2 (10, 1)\n", temp);
      else
        printf("Nothing stored at array2 (10, 1) yet!\n");
    
      temp = getArray(array1, 5, 3);
      if(temp != 0)
        printf("%d at array1 (5, 3)\n", temp);
      else
        printf("Nothing stored at array1 (5, 3) yet!\n");
      
      temp = getArray(array2, 10, 1);
      if(temp != 0)
        printf("%d at array2 (10, 1)\n", temp);
      else
        printf("Nothing stored at array2 (10, 1) yet!\n");
    }
    Thanks for your help!

    Jack
    Last edited by jack0121; 05-07-2007 at 06:46 PM.

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Do you plan on free()'ing the array?

    Consider, int main(... over main() (avoid confusion)
    Also consider typedef'ing int **array to avoid confusion.

    I think you should narrow down your testing, to find the problem either in setArray, getArray or createArray...
    For example, add debugging lines throught your code: perror("Setting array element 1"); setArray(...) perror("set array element 1"); to help find your segfault.
    Last edited by zacs7; 05-07-2007 at 07:03 PM.

  3. #3
    Registered User
    Join Date
    May 2007
    Posts
    2
    Quote Originally Posted by zacs7 View Post
    I think you should narrow down your testing, to find the problem either in setArray, getArray or createArray...
    For example, add debugging lines throught your code: perror("Setting array element 1"); setArray(...) perror("set array element 1"); to help find your segfault.
    Sorry, I should have added that the Segmentation Fault occurs when calling both getArray() and setArray(). createArray() works fine I think - but I guess the error could lie in that function all the same. I don't really see a logical error - but obviously there is one - cause I'm relatively new to C (not programming generally though).

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You don't check if malloc fails for one, you just continue regardless. What could be happening is: your malloc fails, and then you try and reference memory that doesn't belong to you.

    FYI, malloc() returns NULL if it fails...

    Here's another way how to dynamically create 2d arrays:
    Code:
    array = malloc(x*y*sizeof(int));
    if(array == NULL)
    {
        perror("Failed to allocate array");
        /* don't continue */
    }
    
    /* array has enough room for x rows, y cols */
    And when you've finished with array, free it, eg free(array);

    Your logical error lies with max_x and max_y (your 2 globals)
    when the first createArray() is called, these values are set for the bounds of the first array. But then you call createArray() again, which overrides the first arrays max_x and max_y with the x and y bounds of array2. Then when you try and set/get the first array your actually referencing out of the bounds of the first array.

    Consider:
    Code:
    typedef struct my2dArray_t {
        int * array_data;
        int max_x, max_y;
    } my2dArray;
    then something like:
    Code:
    int main(void)
    {
        my2dArray * array1;
        array1.max_x = 20;
        array1.max_y = 40;
        createArray(array1); // read from array1 struct (20 rows, 40 cols);
        // set + get
        free(array1.array_data);// make a func to do this!
        return 0;
    }
    Last edited by zacs7; 05-07-2007 at 07:37 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > return &array[0];
    Surely just
    return array;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to combine these working parts??
    By transgalactic2 in forum C Programming
    Replies: 0
    Last Post: 02-01-2009, 08:19 AM
  2. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  3. Working with random like dice
    By SebastionV3 in forum C++ Programming
    Replies: 10
    Last Post: 05-26-2006, 09:16 PM
  4. Need help understanding info in a header file
    By hicpics in forum C Programming
    Replies: 8
    Last Post: 12-02-2005, 12:36 PM
  5. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM