Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Assigning values to char arrays (http://www.velocityreviews.com/forums/t548765-assigning-values-to-char-arrays.html)

emyl 11-01-2007 11:56 PM

Assigning values to char arrays
 
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.

Answers greatly appreciated.

Regards, Emyl.


Richard 11-02-2007 12:04 AM

Re: Assigning values to char arrays
 
emyl <kwcpsn@yahoo.com> 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.
>
> Answers greatly appreciated.
>
> Regards, Emyl.


Richard Heathfield 11-02-2007 12:32 AM

Re: Assigning values to char arrays
 
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.
>
> Answers greatly appreciated.


Your definition:

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@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

CBFalconer 11-02-2007 12:47 AM

Re: Assigning values to char arrays
 
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 11-02-2007 01:04 AM

Re: Assigning values to char arrays
 
Richard <rgrdev@gmail.com> writes:

> emyl <kwcpsn@yahoo.com> 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.
>>
>> Answers greatly appreciated.
>>
>> Regards, Emyl.


emyl 11-02-2007 02:12 AM

Re: Assigning values to char arrays
 
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
time to answer.

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.
If I could I'd buy
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 11-02-2007 04:33 AM

Re: Assigning values to char arrays
 
On Nov 2, 5:32 am, Richard Heathfield <r...@see.sig.invalid> 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.

>
> > Answers greatly appreciated.

>
> Your definition:
>
> 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 11-02-2007 06:07 AM

Re: Assigning values to char arrays
 
somenath said:

> On Nov 2, 5:32 am, Richard Heathfield <r...@see.sig.invalid> 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
instead.

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

somenath 11-02-2007 06:31 AM

Re: Assigning values to char arrays
 
On Nov 2, 11:07 am, Richard Heathfield <r...@see.sig.invalid> wrote:
> somenath said:
>
> > On Nov 2, 5:32 am, Richard Heathfield <r...@see.sig.invalid> 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
> instead.


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 11-02-2007 06:59 AM

Re: Assigning values to char arrays
 
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@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999


All times are GMT. The time now is 11:54 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.