Hi all,
I have a the following simple piece of code which has taken me hours
to try and sort out the problem, but still unable to find what is
wrong.
void main( void )
int main (void) /* main always returns int */
{
char (*string)[20]; .......................(1)
This doesn't do what you think it does. You are declaring a pointer
to a single 20-element array of char.
Here's a handy chart that may help:
char h; /* h is a single char */
char *h; /* h is a pointer to char */
char **h; /* h is a pointer to a pointer to char */
char h[N]; /* h is an N-element array of char */
char *h[N]; /* h is an N-element array of pointers to
char */
char **h[N]; /* h is an N-element array of pointers to
pointers to char */
char (*h)[N]; /* h is a pointer to an N-element array of
char */
char h[M][N]; /* h is an M-element array of N-element
arrays of char */
char *h[M][N]; /* h is an M-element array of N-element
arrays of pointers to char */
char (*h)[M][N]; /* h is a pointer to an M-element array
of N-element arrays of char */
char *(*h)[M][N]; /* h is a pointer to an M-element array
of N-element arrays of pointers to char
*/
char (*h[M])[N]; /* h is an M-element array of pointers
to N-element arrays of char */
char *(*h[M])[N]; /* h is an M-element array of pointers
to N-element arrays of pointer to char
*/
char (**h)[N]; /* h is a pointer to a pointer to an
N-element array of char */
....and then it starts getting ugly, but I think you can work out the
pattern from there.
To do what you want to do, you don't want to mess with pointers to
arrays. Trust me. There's a reason they aren't used much.
Here's a method that's 70% less headache-inducing:
#include <stdlib.h>
#define STRSIZE 20
#define ARRSIZE 10
int main (void)
{
char **p; /* p will become an array of pointers to char */
int i;
/*
** allocate a block of memory big enough to hold 10 pointers to
char,
** assign the address to p.
*/
p = malloc (ARRSIZE * sizeof *p)
if (p)
{
/*
** allocate the individual 20-element arrays of char, assign
each
** address to p
*/
p[0] = NULL; /* make the first array element NULL */
for (i = 1; i < ARRSIZE; i++)
{
p = malloc (sizeof **p * STRSIZE);
}
}
return 0;
}
Of course, this doesn't guarantee that all the memory is contiguous.
If that's a requirement, you'll have to do something else. Personally
I'd allocate a single huge block of ARRSIZE * STRSIZE characters, and
set up a separate array of pointers into it:
#include <stdio.h>
#include <stdlib.h>
#define STRSIZE 20
#define ARRSIZE 10
int main (void)
{
char *p; /* single big array of bytes */
char *h[ARRSIZE]; /* array of pointers into p */
p = malloc (STRSIZE * ARRSIZE * sizeof *p);
if (p)
{
int i;
h[0] = NULL;
for (i = 1; i < arrsize; i++)
{
/*
** get the address of each 20-element substring in p,
assign
** to h; h[1] = &p[20], h[2] = &p[40], etc.
*/
h = &p[i*STRSIZE];
}
}
return 0;
}
It looks ugly, but it's still less of a pain in the ass than dealing
with pointers to arrays.
string = malloc(10 * sizeof *string); .....(2)
string[0] = NULL; .........................(3)
}
Basically, I am allocating memory to an array of strings of 20 chars
max, and setting element 0 of the array to be a NULL value.
Lines (1) to (2) work OK, but line (3) does not work. I wish to set
the string of element 0 to be a NULL value, but keeps getting an error
saying:
"left operand must be l-value"
This is going to be a bit twisted, and I'll probably botch it, but
here goes.
Remember that you have declared string as a pointer to a 20-element
array of char. Remember that the subscript expression a is
evaluated as *(a + i); the type of that expression is the base type of
a. IOW, string[0] is evaluated as *(string + 0), or just *string, and
the type of *string is 20-element array of char.
An object of array type may not appear on the left-hand side of an
assignment expression, which is why you got the error above. It's the
equivalent of writing
int a[10];
a = NULL;
Such an operation is not allowed in C. Array objects cannot be
assigned to.
Yet another reason why you don't want to use pointers to arrays. In
almost 15 years of writing code professionally I've never had occasion
to use them. I'm sure they're useful in some obscure context, but I
haven't found it yet.