Velocity Reviews > Assigning values to char arrays

Assigning values to char arrays

emyl
Guest
Posts: n/a

 11-01-2007
Hi all,

here's an elementary question. Assume I have declared two variables,

char *a, **b;

I can then give a value to a like

a="hello world";

The question is, how should I assign values to b? A simple

b[0]="string";

results in a segmentation fault.

Regards, Emyl.

Richard
Guest
Posts: n/a

 11-02-2007
emyl <(E-Mail Removed)> writes:

> Hi all,
>
> here's an elementary question. Assume I have declared two variables,
>
> char *a, **b;

b is a pointer to a char pointer.

>
> I can then give a value to a like
>
> a="hello world";
>
> The question is, how should I assign values to b? A simple
>
> b[0]="string";

*b = "s";

>
> results in a segmentation fault.
>
>
> Regards, Emyl.

Richard Heathfield
Guest
Posts: n/a

 11-02-2007
emyl said:

> Hi all,
>
> here's an elementary question. Assume I have declared two variables,
>
> char *a, **b;
>
> I can then give a value to a like
>
> a="hello world";
>
> The question is, how should I assign values to b? A simple
>
> b[0]="string";
>
> results in a segmentation fault.
>

char *a, **b;

reserves sufficient storage for a pointer-to-char named a, and a
pointer-to-pointer-to-char named b.

a="hello world";

assigns a value to this pointer-to-char, the value in question being the
address of the first character in the given string literal.

But b[0]="string"; is a problem, not because there's anything wrong with
the syntax, but because you've made an incorrect assumption.

b is a pointer-to-pointer-to-char, but you haven't pointed it to any
pointers-to-char, so it is currently indeterminate. b[0]="string"; is
*not* an attempt to give a value to b. It is an attempt to give a value to
b[0]. But b[0] is meaningless unless b has a meaningful value.

You can give b a meaningful value in any of several ways, but the most
obvious is to allocate some fresh memory for it:

#include <stdlib.h>

/* allocate memory for some pointers-to-char */
char **cpalloc(size_t n)
{
char **ptr = malloc(n * sizeof *ptr);
if(ptr != NULL)
{
while(n--)
{
ptr[n] = NULL;
}
}
return ptr;
}

#include <stdio.h>

int main(void)
{
char *a, **b;
a = "what has it got in its pocketses?";
b = cpalloc(2);
if(b != NULL)
{
b[0] = "string";
b[1] = "nothing";

printf("%s\n", a);
printf("%s or %s\n", b[0], b[1]);

free(b);
}
return 0;
}

Be careful. The cpalloc function written above does not allocate storage
for strings, only for a collection of pointers to char. A pointer to char
is sufficient for pointing at a string, but not for storing it.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999

CBFalconer
Guest
Posts: n/a

 11-02-2007
emyl wrote:
>
> here's an elementary question. Assume I have declared two variables,
> char *a, **b;
> I can then give a value to a like
> a="hello world";
> The question is, how should I assign values to b? A simple
> b[0]="string";
> results in a segmentation fault.

"char **b;" declares a pointer to a pointer to char. You could
initialize it with "b = &a;" (provided the a declaration is
present). Then **b is a[0].

However note that your initialization of <a = "hello world";>
leaves a pointing to an unmodifiable string.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Richard
Guest
Posts: n/a

 11-02-2007
Richard <(E-Mail Removed)> writes:

> emyl <(E-Mail Removed)> writes:
>
>> Hi all,
>>
>> here's an elementary question. Assume I have declared two variables,
>>
>> char *a, **b;

>
> b is a pointer to a char pointer.
>
>>
>> I can then give a value to a like
>>
>> a="hello world";
>>
>> The question is, how should I assign values to b? A simple
>>
>> b[0]="string";

>
> *b = "s";
>

*slaps cold water on face*

Sorry. That was bullshit. I thought I had included the initialisation
line. See other replies.

Scary.

>>
>> results in a segmentation fault.
>>
>>
>> Regards, Emyl.

emyl
Guest
Posts: n/a

 11-02-2007
BIG sigh of relief... Thanks all for your replies. More
specifically,

Richard: Your suggestion is one of the bazillion things I had tried
more or less a
t random. Like you noticed, it won't work. Thanks for taking the

Richard H.: My heartfelt thanks for a crystal clear answer that works
like a charm a
nd is general enough to use it in the broader context of my project.
a beer to you and candy to your kids..............

Chuck F.: Thanks a lot for your answer. Of all the simple
possibilities it was the
only one I didn't try, and I guess the only correct one. If I had
thought of that
I'd have had enough of a clue to solve the problem.

somenath
Guest
Posts: n/a

 11-02-2007
On Nov 2, 5:32 am, Richard Heathfield <(E-Mail Removed)> wrote:
> emyl said:
>
>
>
>
>
> > Hi all,

>
> > here's an elementary question. Assume I have declared two variables,

>
> > char *a, **b;

>
> > I can then give a value to a like

>
> > a="hello world";

>
> > The question is, how should I assign values to b? A simple

>
> > b[0]="string";

>
> > results in a segmentation fault.

>

>
>
> char *a, **b;
>
> reserves sufficient storage for a pointer-to-char named a, and a
> pointer-to-pointer-to-char named b.
>
> a="hello world";
>
> assigns a value to this pointer-to-char, the value in question being the
> address of the first character in the given string literal.
>
> But b[0]="string"; is a problem, not because there's anything wrong with
> the syntax, but because you've made an incorrect assumption.
>
> b is a pointer-to-pointer-to-char, but you haven't pointed it to any
> pointers-to-char, so it is currently indeterminate. b[0]="string"; is
> *not* an attempt to give a value to b. It is an attempt to give a value to
> b[0]. But b[0] is meaningless unless b has a meaningful value.
>
> You can give b a meaningful value in any of several ways, but the most
> obvious is to allocate some fresh memory for it:
>
> #include <stdlib.h>
>
> /* allocate memory for some pointers-to-char */
> char **cpalloc(size_t n)
> {
> char **ptr = malloc(n * sizeof *ptr);

> if(ptr != NULL)
> {
> while(n--)
> {
> ptr[n] = NULL;
> }
> }

I have one question . Can memset be used as
memset(ptr,0,n);
Instead of the while loop ?

> return ptr;

Richard Heathfield
Guest
Posts: n/a

 11-02-2007
somenath said:

> On Nov 2, 5:32 am, Richard Heathfield <(E-Mail Removed)> wrote:

<snip>

>> char **ptr = malloc(n * sizeof *ptr);

>
>> if(ptr != NULL)
>> {
>> while(n--)
>> {
>> ptr[n] = NULL;
>> }
>> }

> I have one question . Can memset be used as
> memset(ptr,0,n);
> Instead of the while loop ?

Not unless you can guarantee that the representation of null pointers on
all target platforms is all-bits-zero. I don't recall that the OP
mentioned any platforms. The code I supplied was portable to any hosted
implementation.

In situations where you /can/ use memset, don't bother - just calloc it

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999

somenath
Guest
Posts: n/a

 11-02-2007
On Nov 2, 11:07 am, Richard Heathfield <(E-Mail Removed)> wrote:
> somenath said:
>
> > On Nov 2, 5:32 am, Richard Heathfield <(E-Mail Removed)> wrote:

>
> <snip>
>
> >> char **ptr = malloc(n * sizeof *ptr);

>
> >> if(ptr != NULL)
> >> {
> >> while(n--)
> >> {
> >> ptr[n] = NULL;
> >> }
> >> }

> > I have one question . Can memset be used as
> > memset(ptr,0,n);
> > Instead of the while loop ?

>
> Not unless you can guarantee that the representation of null pointers on
> all target platforms is all-bits-zero. I don't recall that the OP
> mentioned any platforms. The code I supplied was portable to any hosted
> implementation.
>
> In situations where you /can/ use memset, don't bother - just calloc it

Many thanks for the response.

But my understanding was in pointer context 0 and NULL is converted to
null pointer. And converting to null pointer is compiler
responsibility. So I thought 0 in memset will be converted to null
pointer (which is system specific).

I would request you to correct me as I am feeling I may be
misunderstood some concept.

Richard Heathfield
Guest
Posts: n/a

 11-02-2007
somenath said:

<snip>

> But my understanding was in pointer context 0 and NULL is converted to
> null pointer. And converting to null pointer is compiler
> responsibility. So I thought 0 in memset will be converted to null
> pointer (which is system specific).
>
> I would request you to correct me as I am feeling I may be
> misunderstood some concept.

You need to separate two very different ideas - *value* and
*representation*. You are quite right that an assignment such as:

char *p;

p = 0; /* ...this... */

requires the compiler to assign p a null pointer value. Let's just assume
for the sake of argument that we're on a platform where a null pointer is
*not* all-bits-zero. In this circumstance, the compiler is obliged to do
any necessary magic to ensure that p ends up with a null pointer value as
a result of the assignment.

But memset is a very different thing indeed. It takes no account whatsoever
of value, and it doesn't know that what you've passed to it is the address
of the first of a bunch of pointers. All it knows is that it has to set a
bunch of bytes to such-and-such, starting at such-and-such an address and
continuing for so-many bytes. It cares about the value you pass only
insofar as it can be represented as an unsigned char, and it doesn't care
a jot about the value of the resulting object.

The memset function can be (isn't!, but can legally be) implemented like
this:

#include <stddef.h>
void *memset(void *s, int c, size_t n)
{
unsigned char *p = s;
while(n--)
{
*p++ = c;
}
return s;
}

As you can see, memset doesn't (and indeed can't) care what kind of
object's bytes it is hacking at, and so it can't distinguish between a
pointer value and some other kind of value. Thus, in the original code,
memset(&ptr[0], 0, n * sizeof *ptr); would merely have set the object
representation to all-bits-zero, without any attempt whatsoever to address
the question of which value the object would have afterwards.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999