pointer array problem

D

DevarajA

termin ha scritto:
consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is already declared as a char* array and the name of an
array becomes a const pointer to the first element of the array. So it
can't be modified to point to other locations.
 
C

Chris Dollin

termin said:
consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because `arr` is an array, and you can't assign to an
entire array - only to elements of one.
 
C

Chris Dollin

DevarajA said:
termin ha scritto:
consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?
Because arr is already declared as a char* array and the name of an
array becomes a const pointer to the first element of the array.

No, /it does not/.

The types are different, as seventeen seconds with `sizeof`
and your favourite compiler - and other experiments - will
support.
 
D

DevarajA

Chris Dollin ha scritto:
DevarajA wrote:

termin ha scritto:
consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is already declared as a char* array and the name of an
array becomes a const pointer to the first element of the array.


No, /it does not/.

The types are different, as seventeen seconds with `sizeof`
and your favourite compiler - and other experiments - will
support.

It doesnt when you use sizeof, initialize with a string literal or use
operator &. In other cases it does. Anyway you're right, it would have
been better to say "it acts like a pointer".
 
C

Chris Dollin

DevarajA said:
Chris Dollin ha scritto:
DevarajA wrote:

termin ha scritto:

consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is already declared as a char* array and the name of an
array becomes a const pointer to the first element of the array.

No, /it does not/.

The types are different, as seventeen seconds with `sizeof`
and your favourite compiler - and other experiments - will
support.

It doesnt when you use sizeof, initialize with a string literal or use
operator &. In other cases it does. Anyway you're right, it would have
been better to say "it acts like a pointer".

No, it would have been better to say that it's an array, and
arrays aren't assignable in C.

Pretending it's a pointer only defers the pain, and gives it
a chance to grow.
 
J

John Bode

termin said:
consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is a 5-element array of pointer to char, not a pointer to a
5-element array of char, and you cannot write to an array object. If
your intent was to create an array of 5 20-character strings, the
general procedure is

#include <stdlib.h>
#include <string.h>

int main(void)
{
char *arr[5];
int i;

for (i = 0; i < sizeof arr / sizeof arr[0]; i++)
{
arr = malloc(sizeof arr * 20);
if (arr)
{
strcpy(arr, "initial string");
}
}

/* do something interesting */
return 0;
}

If your intent was to create a single 20-element array of char, you
would do one of the following:

1. char *arr;
...
arr = malloc(20 * sizeof *arr);
if (arr)
{
strcpy(arr, "some string value");
}

2. char (*arr)[20];
...
arr = malloc(sizeof *arr); // note difference
if (arr)
{
strcpy(*arr, "some string value"); // note difference
}

The second method isn't as commonly used, mainly because it isn't as
flexible and introduces an extra level of indirection. I just included
it for completeness.

Remember:

char *arr[5]; -- arr is array of pointer to char
char (*arr)[5]; -- arr is pointer to array of char
 
N

Netocrat

Chris said:
DevarajA said:
Chris Dollin ha scritto:
DevarajA wrote:


termin ha scritto:

consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is already declared as a char* array and the name of an
array becomes a const pointer to the first element of the array.

Strictly speaking it becomes not a "const pointer" but a "non-lvalue
pointer".

The string literal initialisation applies to the string literal itself,
not the array being initialised, which doesn't decay and remains an
array.

Perhaps "it decays to a pointer".
No, it would have been better to say that it's an array, and
arrays aren't assignable in C.

For the reply to this specific post, you are right.
Pretending it's a pointer only defers the pain, and gives it
a chance to grow.

But not being aware that an array in most situations decays to a
pointer can become just as painful.
 
O

ozbear

consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is a 5-element array of pointer to char, not a pointer to a
5-element array of char, and you cannot write to an array object. If
your intent was to create an array of 5 20-character strings, the
general procedure is

#include <stdlib.h>
#include <string.h>

int main(void)
{
char *arr[5];
int i;

for (i = 0; i < sizeof arr / sizeof arr[0]; i++)
{
arr = malloc(sizeof arr * 20);
if (arr)
{
strcpy(arr, "initial string");
}
}

/* do something interesting */
return 0;
}

<snip>

I believe the malloc call
arr = malloc(sizeof arr * 20);
should have been
arr = malloc(sizeof arr[0] * 20);
or, probably better
arr = malloc(20);

The original overallocates by a factor of sizeof(arr) since
arr is a char pointer, not a char.

Oz
 
L

Lawrence Kirby

Chris Dollin ha scritto:
DevarajA wrote:

termin ha scritto:

consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?


Because arr is already declared as a char* array and the name of an
array becomes a const pointer to the first element of the array.

arr is declared (and also defined) as an array of 5 pointers to char. It
is NOT declared as a char *.
It doesnt when you use sizeof, initialize with a string literal or use
operator &.

In those cases an array operand/initialiser is used directly, ...
In other cases it does.

.... in other cases it is converted to a pointer to the first element of
the array. A pointer to the first element of arr has type char **, not
char *.
Anyway you're right, it would have
been better to say "it acts like a pointer".

The significant point here is not that it evaluates to a pointer, it is
that it is not modifiable i.e. cannot appear on the LHS of an assignment
operator.

Lawrence
 
J

John Bode

ozbear said:
consider this

char *arr[5];

why doesn't

arr=malloc(20);

this work ?

Because arr is a 5-element array of pointer to char, not a pointer to a
5-element array of char, and you cannot write to an array object. If
your intent was to create an array of 5 20-character strings, the
general procedure is

#include <stdlib.h>
#include <string.h>

int main(void)
{
char *arr[5];
int i;

for (i = 0; i < sizeof arr / sizeof arr[0]; i++)
{
arr = malloc(sizeof arr * 20);
if (arr)
{
strcpy(arr, "initial string");
}
}

/* do something interesting */
return 0;
}

<snip>

I believe the malloc call
arr = malloc(sizeof arr * 20);
should have been
arr = malloc(sizeof arr[0] * 20);
or, probably better
arr = malloc(20);

The original overallocates by a factor of sizeof(arr) since
arr is a char pointer, not a char.


Yeah, typo. That was supposed to read

arr = malloc(sizeof *arr * 20);

I make it a habit to include the sizeof for the target, rather than
just a raw number of bytes; for one thing, I think it makes the intent
of the code clearer (I'm allocating N elements of M size, rather than X
bytes), and for another, I'm usually allocating arrays of something
other than char, so I have to include the sizeof anyway.
 

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,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top