Thread: need help with dynamic array syntax

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    2

    need help with dynamic array syntax

    I am working on building a ray tracer and unfortunately I am stuck having to use someone's old code to build on and the old code is done In C. My specialities are in C++ (STL) and Java.

    What I need help with is setting up a 2-D dynamic array. What is happening is that the user needs to be able to pass in the number of rows of pixels and the screen resolution which will ultimately determine the 2-D array of pixels which will be displayed.

    If this was in C++ it would be a simple matter of vectors however, I don't know before hand how may rows will be passed in (it could be 100, 500 or more).

    I have very little (none infact) experience using malloc or any other memory allocation call. what is the simplest and most efficent syntax to create a dynamic array in C?

    I have searched these forums, searched the web, and read the FAQs and have come up short on finding a useable answer.

    thanks in advance.

  2. #2
    Unregistered User
    Join Date
    Sep 2005
    Location
    Antarctica
    Posts
    341
    what is the array an array of? Is it ints? If so, you would do this:

    int *myArray = malloc(numItems * sizeof(int));

    dont' forget to call free(myArray) when you are finished with it.

  3. #3
    Sr. Software Engineer filker0's Avatar
    Join Date
    Sep 2005
    Location
    West Virginia
    Posts
    235
    You're doing 2D arrays? You need to do a bit more than rockytriton's suggestion describes.

    Assuming that both dimensions are variable, one (not terribly efficient) solution is to allocate an array of pointers to your rows, as in:
    Code:
    int scan;
    unsigned int **matrix;
    matrix = (unsigned int **) malloc(num_scans * sizeof(unsigned int *));
    for (scan = 0; scan < num_scans; ++scan)
    {
        matrix[scan] = malloc(pixels_per_scan * sizeof(unsigned int));
    }
    Of course, you should always check for NULL returns from malloc. This will allow you to access the "pixels" as "matrix[row][column]". To get rid of one of these beasts, you must
    do something like:
    Code:
    int scan;
    for (scan = 0; scan < num_scans; ++scan)
    {
        free(matrix[scan]);
    }
    free(matrix);
    A better way to do it is to use a single allocation and a bit of pointer arithmetic. There are many ways to solve this in C, and which you choose is a matter of taste and style. I don't know enough about your requirements or what the calling code looks like. I would probably use an object oriented approach in C creating a structure that contained a pointer to the memory used for the pixels plus the height and width of the bitmap, then I'd write a "new" function that allocates and initializes one of these structures, a "destroy" function that frees one of these structures, and a set of pixel operations (set/get/etc.) that work on these bitmaps.

    GCC (at least recent versions thereof) now supports a variable-length array syntax.

    From "info gcc" on a Linux system...
    5.14 Arrays of Variable Length
    ==============================

    Variable-length automatic arrays are allowed in ISO C99, and as an
    extension GCC accepts them in C89 mode and in C++. (However, GCC's
    implementation of variable-length arrays does not yet conform in detail
    to the ISO C99 standard.) These arrays are declared like any other
    automatic arrays, but with a length that is not a constant expression.
    The storage is allocated at the point of declaration and deallocated
    when the brace-level is exited. For example:
    Code:
         FILE *
         concat_fopen (char *s1, char *s2, char *mode)
         {
           char str[strlen (s1) + strlen (s2) + 1];
           strcpy (str, s1);
           strcat (str, s2);
           return fopen (str, mode);
         }
    Jumping or breaking out of the scope of the array name deallocates the
    storage. Jumping into the scope is not allowed; you get an error
    message for it.

    You can use the function `alloca' to get an effect much like
    variable-length arrays. The function `alloca' is available in many
    other C implementations (but not in all). On the other hand,
    variable-length arrays are more elegant.

    There are other differences between these two methods. Space allocated
    with `alloca' exists until the containing _function_ returns. The
    space for a variable-length array is deallocated as soon as the array
    name's scope ends. (If you use both variable-length arrays and
    `alloca' in the same function, deallocation of a variable-length array
    will also deallocate anything more recently allocated with `alloca'.)

    You can also use variable-length arrays as arguments to functions:
    Code:
         struct entry
         tester (int len, char data[len][len])
         {
           /* ... */
         }
    The length of an array is computed once when the storage is allocated
    and is remembered for the scope of the array in case you access it with
    `sizeof'.

    If you want to pass the array first and the length afterward, you can
    use a forward declaration in the parameter list--another GNU extension.
    Code:
         struct entry
         tester (int len; char data[len][len], int len)
         {
           /* ... */
         }
    The `int len' before the semicolon is a "parameter forward
    declaration", and it serves the purpose of making the name `len' known
    when the declaration of `data' is parsed.
    The above is not really portable, but if you're running on Linux or a similar system using GCC, you might be able to get away with it. Also, you cannot return one of these variable length arrays to a calling program, as it will go out of scope and be deallocated.
    Last edited by filker0; 10-11-2005 at 01:06 PM. Reason: Add a reference for GCC

  4. #4
    Registered User
    Join Date
    Oct 2005
    Posts
    2

    thanks

    wow, I am impressed with both the speed and detail of the help I have recieved here.

    I am kind of embarrased to say this but I actually found a work around to the dynamic array situation. I discovered that I ultimately don't need to save the pixel info in a matrix. one of the final requirements for the program is to print the pixel color info into a .ppm file for use in other programs. so when I find the color of the pixel I am working on I print the color out to the file immediately instead of storing it into a matrix.

    I hope you don't feel that your work was for nothing. I did read all that you posted and have bookmarked the page for furture reference as I am sure that I will need the information again later. and anyway, when the next person comes to the forums with the same question they can benefit from the wisdom as well (assuming they do a search first).

    again thanks for the info!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  2. Using VC Toolkit 2003
    By Noobwaker in forum Windows Programming
    Replies: 8
    Last Post: 03-13-2006, 07:33 AM
  3. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  4. using c++ in c code
    By hannibar in forum C Programming
    Replies: 17
    Last Post: 10-28-2005, 09:09 PM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM