dynaminc two dimensional array

Discussion in 'C Programming' started by cerr, Sep 28, 2013.

  1. cerr

    cerr Guest

    Hi There,

    I'm trying to create a two dimensional array to store a collection of artist & song names.

    I've tried this:
    #include <stdio.h>
    #include <stdlib.h>
    int main(void){
    char *test;

    test = (char*) malloc(1);
    test[0] = (char*) malloc(50);
    test[0] = "artist";
    test[0][0] = "song";


    return 0;
    }

    but get error: subscripted value is neither array nor pointer nor vector

    why is this?

    Thanks
    cerr, Sep 28, 2013
    #1
    1. Advertising

  2. On Saturday, September 28, 2013 10:40:54 PM UTC+1, cerr wrote:
    >
    > I'm trying to create a two dimensional array to store a collection of
    > artist & song names.
    >

    2 dimensional arrays don't work well in C. Introductory books tend to
    be less than helpful about this, presenting 2d arrays early on in the
    section on array syntax.
    You can't easily create a 2d array dynamically. Which means that if
    you don't know the dimensions at compile time, which is the normal
    situation, they are pretty useless.

    What most people do is allocate a 1d array using array = malloc(width * height * sizeof(element)), then access using array[y *width+x].
    Malcolm McLean, Sep 28, 2013
    #2
    1. Advertising

  3. On Sat, 28 Sep 2013 14:40:54 -0700 (PDT), cerr <>
    wrote:

    >Hi There,
    >
    >I'm trying to create a two dimensional array to store a collection of artist & song names.
    >
    >I've tried this:
    >#include <stdio.h>
    >#include <stdlib.h>
    >int main(void){
    > char *test;
    >
    > test = (char*) malloc(1);


    This allocates space sufficient to hold ONE byte.

    > test[0] = (char*) malloc(50);


    This attempts to store a pointer value in that byte. While there
    probably are some systems where that will work, on most PC systems,
    the pointer value requires either 4 or 8 bytes.

    > test[0] = "artist";


    This does not copy the string value to the address you think test[0]
    olds. What it does is store the address of the string literal in
    test[0] itself. The end result is that the address of the allocated
    memory (which was in test[0]) is now permanently lost, thus creating a
    memory leak.

    > test[0][0] = "song";


    You defined test as a char*. Therefore test[0] must be a char. It is
    illegal to apply the second [0] operator to an expression of that
    type. (The subscript operator is only meaningful for arrays and
    pointers.) Thus the error message. In order for this code to be
    legal, test [0][0] would need to have type char*. That would force
    test[0] to have type char** which in turn would require test to be of
    type char***.

    >return 0;
    >}
    >
    >but get error: subscripted value is neither array nor pointer nor vector


    Since C does not have vectors, you obviously compiled this as C++. If
    you are going to use C++, there are easier approaches but they need to
    be discussed in a C++ group.

    --
    Remove del for email
    Barry Schwarz, Sep 29, 2013
    #3
  4. On Sunday, September 29, 2013 5:14:42 AM UTC+7, Malcolm McLean wrote:

    > What most people do is allocate a 1d array using
    > array = malloc(width * height * sizeof(element)),
    > then access using array[y *width+x].


    This is the easiest and, arguably, most straightforward way.

    > 2 dimensional arrays don't work well in C.


    This is debatable. As long as one fully understands the
    syntax, fully understands the difference between declaring
    an array and declaring a pointer, and keeps in mind the
    difference between fixed and variable dimensions, then
    I think C's usage is quite elegant and flexible.

    For example
    char (*Arr)[5][6] = malloc(9 * sizeof *Arr);
    allocates array Arr[9][5][6] dynamically.
    (I realize that, by itself, this might be silly
    and complicated overkill for what OP wants to do.)

    > Which means that if
    > you don't know the dimensions at compile time, which is the normal
    > situation, they are pretty useless.


    By declaring conceptual arrays via *** rather than [][][]
    one can get sparse arrays which don't waste memory.

    It's been a decade since I posted my example of such.
    http://fabpedigree.com/james/wnim.htm
    (This program will get much ridicule, the sparse array
    syntax perhaps being the least offensive part. I'll
    unsubscribe from c.l.c for a week or two and let the
    screaming die down.)

    James Dow Allen
    James Dow Allen, Sep 29, 2013
    #4
  5. cerr <> writes:

    > I'm trying to create a two dimensional array to store a collection of
    > artist & song names.


    2d array work just like 1d arrays, because that's what they are -- 1d
    arrays on elements that just happen to arrays themselves.

    I imagine you want an array or pairs of strings (well, pointers to
    strings) -- one for the artist and one for the song. That's easy to do,
    though there is wrinkle: C type syntax need a pair of brackets to write
    "a pointer to an array". Here's an sequence of related allocations:

    int *data; // will point to the first int
    data = malloc(50 * sizeof *data); // 50 ints

    int (*data)[2]; // will point to the first array of 2 ints
    data = malloc(50 * sizeof *data); // 50 pairs of ints

    char **data; // will point to the first pointer to a string
    data = malloc(50 * sizeof *data); // 50 pointers to strings

    char *(*data)[2]; // will point to the first array of 2 pointers to strings
    data = malloc(50 * sizeof *data); // 50 pairs of pointers to strings

    Notice how the allocation is exactly the same. Only the type of the
    pointer that picks up the result changes.

    However, why not use an array of structures? That way the two parts can
    have sensible names.

    <snip>
    --
    Ben.
    Ben Bacarisse, Sep 29, 2013
    #5
  6. Barry Schwarz <> writes:
    > On Sat, 28 Sep 2013 14:40:54 -0700 (PDT), cerr <>
    > wrote:

    [...]
    >>but get error: subscripted value is neither array nor pointer nor vector

    >
    > Since C does not have vectors, you obviously compiled this as C++. If
    > you are going to use C++, there are easier approaches but they need to
    > be discussed in a C++ group.


    No, gcc gives that error message even in C mode. And the word
    "vector" in the message doesn't refer to C++'s std::vector, but to
    a gcc extension described here:
    http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Vector-Extensions.html

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 29, 2013
    #6
  7. Malcolm McLean <> writes:
    > On Saturday, September 28, 2013 10:40:54 PM UTC+1, cerr wrote:
    >> I'm trying to create a two dimensional array to store a collection of
    >> artist & song names.
    >>

    > 2 dimensional arrays don't work well in C. Introductory books tend to
    > be less than helpful about this, presenting 2d arrays early on in the
    > section on array syntax.
    > You can't easily create a 2d array dynamically. Which means that if
    > you don't know the dimensions at compile time, which is the normal
    > situation, they are pretty useless.
    >
    > What most people do is allocate a 1d array using array = malloc(width
    > * height * sizeof(element)), then access using array[y *width+x].


    Strictly speaking, a 2-dimensional array in C is nothing more or
    less than a 1-dimensional array of 1-dimensional arrays.

    Such arrays are inflexible, and it's often more useful to emulate
    more dynamic data structures that act like 2-dimensional arrays.

    If your compiler supports them, you can also use variable-length arrays
    (VLAs). For example:

    #include <stdlib.h>
    int main(void) {
    size_t rows = 10;
    size_t cols = 20;
    typedef double arr[rows][cols];
    arr *arr_ptr = malloc(sizeof *arr_ptr);
    if (arr_ptr == NULL) {
    exit(EXIT_FAILURE);
    }
    (*arr_ptr)[5][15] = 42;
    }

    (*arr_ptr) is a continguous 10 by 20 element 2D array, and its
    elements are accessible using the same indexing notation used for
    a 2D array whose dimensions are compile-time constants.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 29, 2013
    #7
  8. cerr

    BartC Guest

    "cerr" <> wrote in message
    news:...

    > I'm trying to create a two dimensional array to store a collection of
    > artist & song names.


    That sounds like a 1-dimensional array, if you want a collection of artist &
    song pairs (perhaps stored as a struct, as has been suggested). (So that if
    an artist has two songs, there will be two entries, and the artist's name
    will occur twice.)

    Or perhaps you mean a matrix, with artists down one side, and songs across
    the top? That probably won't be very useful unless perhaps some songs have
    been recorded by one than one artist, but it will largely be sparse.

    Or maybe, you mean a thin matrix, 2 elements wide, with those two elements
    storing the artist and song name, with multiple artist+song combinations
    down the length? You can simplify that by just having two single
    1-dimensional arrays, if you don't want to combine the two data items into a
    struct.

    You should anyway clarify the sort of data structure you want. Then it might
    be easier to code for. Try drawing a diagram.

    --
    Bartc
    BartC, Sep 29, 2013
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cnote828

    Dynaminc Table

    cnote828, May 2, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    335
    Karl Seguin [MVP]
    May 2, 2006
  2. Alf P. Steinbach
    Replies:
    0
    Views:
    432
    Alf P. Steinbach
    Aug 18, 2003
  3. John Harrison
    Replies:
    4
    Views:
    6,922
    Default User
    Aug 19, 2003
  4. Icosahedron
    Replies:
    8
    Views:
    650
    Vivek
    Aug 21, 2003
  5. Venkat
    Replies:
    4
    Views:
    970
    Venkat
    Dec 5, 2003
Loading...

Share This Page