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?

    cerr, Sep 28, 2013
    1. Advertisements

  2. 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
    1. Advertisements

  3. This allocates space sufficient to hold ONE byte.
    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.
    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.
    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***.
    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.
    Barry Schwarz, Sep 29, 2013
  4. This is the easiest and, arguably, most straightforward way.
    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.)
    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.
    (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
  5. 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.

    Ben Bacarisse, Sep 29, 2013
  6. 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:
    Keith Thompson, Sep 29, 2013
  7. 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) {
    (*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, Sep 29, 2013
  8. cerr

    BartC Guest

    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

    You should anyway clarify the sort of data structure you want. Then it might
    be easier to code for. Try drawing a diagram.
    BartC, Sep 29, 2013
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.