Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Array of structs with strings (http://www.velocityreviews.com/forums/t600556-array-of-structs-with-strings.html)

goodTweetieBird 03-21-2008 02:25 AM

Array of structs with strings
 

In C I have seen the idiom

char *name = "Tweety";

and have been assured that it is legit. However I have doubts about
the string assignments in the example below I found on the net. Are
these string assignments valid?

Thanks

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>

typedef struct robot ROBOT;

struct robot {
char *name;
int energy;
};

int main() {
int i;

ROBOT robots[3];

robots[0].name = "Lunar Lee";
robots[0].energy = 50;
robots[1].name = "Planetary Pete";
robots[1].energy = 20;

....

Eric Sosman 03-21-2008 02:35 AM

Re: Array of structs with strings
 
goodTweetieBird wrote:
> In C I have seen the idiom
>
> char *name = "Tweety";
>
> and have been assured that it is legit. However I have doubts about
> the string assignments in the example below I found on the net. Are
> these string assignments valid?
>
> Thanks
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> #include <stdio.h>
>
> typedef struct robot ROBOT;
>
> struct robot {
> char *name;
> int energy;
> };
>
> int main() {
> int i;
>
> ROBOT robots[3];
>
> robots[0].name = "Lunar Lee";
> robots[0].energy = 50;
> robots[1].name = "Planetary Pete";
> robots[1].energy = 20;


Yes, they are valid. `robots[n].name' is a char*
(for n == 0,1,2), just as `name' is, so anything you
can do with `name' can also be done with `robots[n].name'.

--
Eric Sosman
esosman@ieee-dot-org.invalid

goodTweetieBird 03-21-2008 02:51 AM

Re: Array of structs with strings
 

> Yes, they are valid. `robots[n].name' is a char*
> (for n == 0,1,2), just as `name' is, so anything you
> can do with `name' can also be done with `robots[n].name'.
>
> --
> Eric Sosman
> esos...@ieee-dot-org.invalid


Thanks for posting but I do not see how it can be valid.
robots[0].name is only a pointer which I thought meant that it is a
few bytes in length. Seems it would soon be writing in unknown areas.

gtb

rpgfan3233 03-21-2008 03:06 AM

Re: Array of structs with strings
 
On Mar 20, 9:51*pm, goodTweetieBird <goodTweetieB...@hotmail.com>
wrote:
> > * * *Yes, they are valid. *`robots[n].name' is a char*
> > (for n == 0,1,2), just as `name' is, so anything you
> > can do with `name' can also be done with `robots[n].name'.

>
> > --
> > Eric Sosman
> > esos...@ieee-dot-org.invalid

>
> Thanks for posting but I do not see how it can be valid.
> robots[0].name is only a pointer which I thought meant that it is a
> few bytes in length. Seems it would soon be writing in unknown areas.
>
> gtb


That's very true. Try taking some rather long input and storing it in
robots[0].name. That way, even the best of compilers can't guess how
much memory should be allocated for robots[0].name to allow for
robots[1].name and robots[2].name. After that, output it, and you can
usually find that robots[1].name and robots[2].name are overwritten.

This is the reason for the malloc() function found in <stdlib.h> -
dynamic memory allocation. You don't know how long it is supposed to
be when you code, so you leave it as a char pointer, which can be
thought of as an array of undeclared length. At run-time, you find out
how long it is supposed to be and you use malloc() to allocate enough
space for the string. When you are done with it, you then free() it.
One very important thing to remember is to use free() to deallocate
the memory when you're finished with the string. Otherwise, you can
end up with a memory leak. The same is true for the calloc() and
realloc() functions - free() them when you're done!

goodTweetieBird 03-21-2008 03:10 AM

Re: Array of structs with strings
 
>
> That's very true. Try taking some rather long input and storing it in
> robots[0].name. That way, even the best of compilers can't guess how
> much memory should be allocated for robots[0].name to allow for
> robots[1].name and robots[2].name. After that, output it, and you can
> usually find that robots[1].name and robots[2].name are overwritten.
>
> This is the reason for the malloc() function found in <stdlib.h> -
> dynamic memory allocation. You don't know how long it is supposed to
> be when you code, so you leave it as a char pointer, which can be
> thought of as an array of undeclared length. At run-time, you find out
> how long it is supposed to be and you use malloc() to allocate enough
> space for the string. When you are done with it, you then free() it.
> One very important thing to remember is to use free() to deallocate
> the memory when you're finished with the string. Otherwise, you can
> end up with a memory leak. The same is true for the calloc() and
> realloc() functions - free() them when you're done!


Sounds like a source of subtle errors.

Thanx,

gtb

Eric Sosman 03-21-2008 03:16 AM

Re: Array of structs with strings
 
goodTweetieBird wrote:
>> Yes, they are valid. `robots[n].name' is a char*
>> (for n == 0,1,2), just as `name' is, so anything you
>> can do with `name' can also be done with `robots[n].name'.

>
> Thanks for posting but I do not see how it can be valid.
> robots[0].name is only a pointer which I thought meant that it is a
> few bytes in length. Seems it would soon be writing in unknown areas.


robots[0].name is a pointer, a char* that can point to
any char anywhere. That char may be the first of a string
of any length whatever; the char* just points to the first
char of the string. It makes no difference how long the
string is; the char* just points to its beginning.

char *name1 = "Peter";
char *name2 = "Linus";
char *name3 = "Anacletus";
char *name4 = "Clement I";
char *name5 = "Evaristus";
...

It doesn't matter how long the string themselves are; the
pointers work the same way anyhow. The pointer name1 points
to P, name2 points to L, and so on, regardless of what comes
after those pointed-to chars.

--
Eric Sosman
esosman@ieee-dot-org.invalid

santosh 03-21-2008 03:52 AM

Re: Array of structs with strings
 
rpgfan3233 wrote:

> On Mar 20, 9:51*pm, goodTweetieBird <goodTweetieB...@hotmail.com>
> wrote:
>> > Yes, they are valid. *`robots[n].name' is a char*
>> > (for n == 0,1,2), just as `name' is, so anything you
>> > can do with `name' can also be done with `robots[n].name'.

>>
>> > --
>> > Eric Sosman
>> > esos...@ieee-dot-org.invalid

>>
>> Thanks for posting but I do not see how it can be valid.
>> robots[0].name is only a pointer which I thought meant that it is a
>> few bytes in length. Seems it would soon be writing in unknown areas.
>>
>> gtb

>
> That's very true. Try taking some rather long input and storing it in
> robots[0].name. That way, even the best of compilers can't guess how
> much memory should be allocated for robots[0].name to allow for
> robots[1].name and robots[2].name. After that, output it, and you can
> usually find that robots[1].name and robots[2].name are overwritten.


This is false. robots[n].name are all of type char *. They can point to
the start of a char or an array of char. In C the construct "whatever"
is called a "string literal". What it does is effectively tell the
compiler to set aside some unnamed array of char big enough to hold the
string "whatever" and a terminating null character. The string literal
in an expression context evaluates to a value of type char *, which is
what you are assigning to robots[n].name. Storage is automatically
allocated for the string literals elsewhere and no memory overwrite
takes place.

> This is the reason for the malloc() function found in <stdlib.h> -
> dynamic memory allocation. You don't know how long it is supposed to
> be when you code,


In the case of a string literal, you do.

> so you leave it as a char pointer, which can be
> thought of as an array of undeclared length.


No.

> At run-time, you find out
> how long it is supposed to be and you use malloc() to allocate enough
> space for the string. When you are done with it, you then free() it.
> One very important thing to remember is to use free() to deallocate
> the memory when you're finished with the string. Otherwise, you can
> end up with a memory leak. The same is true for the calloc() and
> realloc() functions - free() them when you're done!


You cannot "free" the space taken by a string literal. However not all
strings are string literals. The following are valid constructs:

char *str = "hello";
char arr[] = "hello";
char arr1[2] = "hello";
char arr2[10] = "hello";
char *ptr = malloc(strlen("hello") + 1);
if (ptr) strcpy(ptr, "hello");
else error();

This is where a memory overwrite occurs:

char *ptr;
strcpy(ptr, "hello");


CBFalconer 03-21-2008 03:52 AM

Re: Array of structs with strings
 
Eric Sosman wrote:
> goodTweetieBird wrote:
>
>> In C I have seen the idiom
>>
>> char *name = "Tweety";
>>
>> and have been assured that it is legit. However I have doubts about
>> the string assignments in the example below I found on the net. Are
>> these string assignments valid?
>>
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> #include <stdio.h>
>>
>> typedef struct robot ROBOT;
>>
>> struct robot {
>> char *name;
>> int energy;
>> };
>>
>> int main() {
>> int i;
>>
>> ROBOT robots[3];
>>
>> robots[0].name = "Lunar Lee";
>> robots[0].energy = 50;
>> robots[1].name = "Planetary Pete";
>> robots[1].energy = 20;

>
> Yes, they are valid. `robots[n].name' is a char*
> (for n == 0,1,2), just as `name' is, so anything you
> can do with `name' can also be done with `robots[n].name'.


You have set the pointer for name to point to a non-writable
constant char. string. So you can't diddle the names. They are
just there. However, you can replace them.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


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


CBFalconer 03-21-2008 04:06 AM

Re: Array of structs with strings
 
santosh wrote:
>

.... snip ...
>
> This is where a memory overwrite occurs:
>
> char *ptr;
> strcpy(ptr, "hello");


No it doesn't. It just blows up, because ptr was never initialized.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


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


Keith Thompson 03-21-2008 05:30 AM

Re: Array of structs with strings
 
goodTweetieBird <goodTweetieBird@hotmail.com> writes:
> In C I have seen the idiom
>
> char *name = "Tweety";
>
> and have been assured that it is legit. However I have doubts about
> the string assignments in the example below I found on the net. Are
> these string assignments valid?
>
> Thanks
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> #include <stdio.h>
>
> typedef struct robot ROBOT;
>
> struct robot {
> char *name;
> int energy;
> };
>
> int main() {
> int i;
>
> ROBOT robots[3];
>
> robots[0].name = "Lunar Lee";
> robots[0].energy = 50;
> robots[1].name = "Planetary Pete";
> robots[1].energy = 20;
>
> ...


Yes.

The comp.lang.c FAQ is at <http://www.c-faq.com/>. See question 1.32
and all of section 6.

--
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


All times are GMT. The time now is 10:30 PM.

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