dynaminc two dimensional array

C

cerr

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
 
M

Malcolm McLean

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].
 
B

Barry Schwarz

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.
 
J

James Dow Allen

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
 
B

Ben Bacarisse

cerr said:
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>
 
K

Keith Thompson

Barry Schwarz said:
[...]
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
 
K

Keith Thompson

Malcolm McLean said:
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.
 
B

BartC

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.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top