C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

question about auto struct variables

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C Language (Moderated)
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Tue Feb 13, 2007 6:22 pm    Post subject: question about auto struct variables Reply with quote



Apologies if this is a newbie question. I'm a relative newcomer to C,
though experienced in other languages (Lisp, Java, Python, ...) I'm
working with a large array Data of bigdatum objects that my boss
creates and doesn't change.

#define IDLEN 200

struct bigdatum {
char id[IDLEN+1];
/* and many other fields... */
};

extern struct bigdatum *Data;

I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

The function usually worked, but it returned garbage maybe 1 out of
100 times, always at different i. A colleague told me not to use the
automatic variable x. He said x is a only copy of Data[i], and once x
goes out of existence, the pointer 'result' may no longer be valid.

My colleague was certainly right. After collapsing two lines into
char *result = Data[i].id;
the code worked perfectly.

My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?) Then 'result' will be set equal
to that pointer and returned. Even when x goes out of existence,
isn't result pointing to the location I want?

Any hints or links to things I should read would be appreciated.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Tim Brown
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables[c.l.c.moderated] Reply with quote



mmcconnell17704 (AT) yahoo (DOT) com wrote:
Quote:
Apologies if this is a newbie question. I'm a relative newcomer to C,
though experienced in other languages (Lisp, Java, Python, ...) I'm
working with a large array Data of bigdatum objects that my boss
creates and doesn't change.

#define IDLEN 200

struct bigdatum {
char id[IDLEN+1];
/* and many other fields... */
};

extern struct bigdatum *Data;

I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

The function usually worked, but it returned garbage maybe 1 out of
100 times, always at different i. A colleague told me not to use the
automatic variable x. He said x is a only copy of Data[i], and once x
goes out of existence, the pointer 'result' may no longer be valid.

My colleague was certainly right. After collapsing two lines into
char *result = Data[i].id;
the code worked perfectly.

My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?) Then 'result' will be set equal
to that pointer and returned. Even when x goes out of existence,
isn't result pointing to the location I want?

Any hints or links to things I should read would be appreciated.

Yes, he is correct. Yes, both x and Data[i] contain the same id[]
characters, but at different locations. The bigdatam x contents are
simply a temporary copy.

The pointer being returned by the function, pointing to x's temporary copy
of the id[] characters, will be left pointing to whatever occupies those
locations after x 'goes out of existence'.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Tim Brown
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables [comp.lang.c.modera Reply with quote



mmcconnell17704 (AT) yahoo (DOT) com wrote:
Quote:
Apologies if this is a newbie question. I'm a relative newcomer to C,
though experienced in other languages (Lisp, Java, Python, ...) I'm
working with a large array Data of bigdatum objects that my boss
creates and doesn't change.

#define IDLEN 200

struct bigdatum {
char id[IDLEN+1];
/* and many other fields... */
};

extern struct bigdatum *Data;

I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

The function usually worked, but it returned garbage maybe 1 out of
100 times, always at different i. A colleague told me not to use the
automatic variable x. He said x is a only copy of Data[i], and once x
goes out of existence, the pointer 'result' may no longer be valid.

My colleague was certainly right. After collapsing two lines into
char *result = Data[i].id;
the code worked perfectly.

My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?) Then 'result' will be set equal
to that pointer and returned. Even when x goes out of existence,
isn't result pointing to the location I want?

Any hints or links to things I should read would be appreciated.

Yes, he is correct. Yes, both x and Data[i] contain the same id[]
characters, but at different locations. The bigdatam x contents are
simply a temporary copy.

The pointer being returned by the function, pointing to x's temporary copy
of the id[] characters, will be left pointing to whatever occupies those
locations after x 'goes out of existence'.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
WillerZ
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables Reply with quote

mmcconnell17704 (AT) yahoo (DOT) com wrote:
Quote:
I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

That function is not valid in C, I assume you are using C++ and should
therefore ask this in a C++ group.

Quote:
My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?)

No, id was declared as an inline array and not a pointer.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Barry Schwarz
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables Reply with quote

On 13 Feb 2007 12:22:22 GMT, mmcconnell17704 (AT) yahoo (DOT) com wrote:

Quote:
Apologies if this is a newbie question. I'm a relative newcomer to C,
though experienced in other languages (Lisp, Java, Python, ...) I'm
working with a large array Data of bigdatum objects that my boss
creates and doesn't change.

#define IDLEN 200

struct bigdatum {
char id[IDLEN+1];
/* and many other fields... */
};

extern struct bigdatum *Data;

I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

The function usually worked, but it returned garbage maybe 1 out of
100 times, always at different i. A colleague told me not to use the
automatic variable x. He said x is a only copy of Data[i], and once x
goes out of existence, the pointer 'result' may no longer be valid.

My colleague was certainly right. After collapsing two lines into
char *result = Data[i].id;
the code worked perfectly.

My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?) Then 'result' will be set equal

The id member of your structure is NOT a pointer. It is an array. It
doesn't point to the data; it contains the data. You are probably
confused by the fact that you appear to be assigning an array to a
pointer. You are not. There is a special rule in C for expressions
of array type such as Data[i].[id]. Unless it is the operand of
either the sizeof or & operators, an expression with type array of T
is EVALUATED as the address of the first element of the array with
type pointer to T (effectively &T[0]). Note that this is part of
expression evaluation and in no way alters the type of the array.

Quote:
to that pointer and returned. Even when x goes out of existence,
isn't result pointing to the location I want?

In your original code, assigning a structure to x copied all the
members of the structure to x, including all the data in the array id.
When you assigned x.id to result, the evaluated address pointed
somewhere inside x. It did not point to the member id in Data[i].
Since id is not a pointer, the value contained in result and the
address of the first element of Data[i].id are not the same. When x
ceased to exist at the exit from the function, the address in result
being returned to the calling program became indeterminate. Any
attempt to evaluate or dereference that address invoked undefined
behavior. Unfortunately, on your system, this undefined behavior
manifested itself as "appearing to work most of the time."

Quote:

Any hints or links to things I should read would be appreciated.

There should be a C yoga class where the mantra is "pointers are not
arrays and arrays are not pointers."


Remove del for email
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Douglas A. Gwyn
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables Reply with quote

<mmcconnell17704 (AT) yahoo (DOT) com> wrote in message
news:clcm-20070213-0020 (AT) plethora (DOT) net...
Quote:
struct bigdatum {
char id[IDLEN+1];
};
static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}
My colleague was certainly right. After collapsing two lines into
char *result = Data[i].id;
the code worked perfectly.
My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?) Then 'result' will be set equal
to that pointer and returned. Even when x goes out of existence,
isn't result pointing to the location I want?

There is still a problem, in that you're now returning a pointer to
a field within the argument object, so if *that* object gets
overwritten, goes out of scope, or is freed then what you point
to is no longer valid.

The basic principle you need is to track how memory is used
to store (representations of) values. Memory can be reused for
different purposes, or can even become unaddressable when
auto or dynamic storage is freed. If you want some data to
persist, you need to store it in a chunk of memory that will hang
around.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Hans-Bernhard Bröker
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables Reply with quote

mmcconnell17704 (AT) yahoo (DOT) com wrote:

Quote:
static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

Undefined behaviour every time you actually return your 'result'
variable and use it to access the data it points to.

Quote:
The function usually worked, but it returned garbage maybe 1 out of
100 times, always at different i. A colleague told me not to use the
automatic variable x.

Using it is not a problem in and of itself. *Returning* a pointer into
it, is.

Quote:
My colleague was certainly right. After collapsing two lines into
char *result = Data[i].id;
the code worked perfectly.

Still too complicated. Your entire function could be simplified to

static char *indexToId(int i) {
return Data[i].id;
}

.... at which point you'ld should start wondering if this function is
worth the effort of writing it.

Quote:
Although x is a copy of Data[i], the id fields of both objects should
be char-pointers pointing to exactly the same location (shouldn't
they?)

No, they shouldn't. They are arrays containing equal data.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Thomas Richter
Guest





PostPosted: Fri Feb 16, 2007 9:47 pm    Post subject: Re: question about auto struct variables Reply with quote

mmcconnell17704 (AT) yahoo (DOT) com wrote:

Quote:
I wrote this function to get the id of the i-th datum.

struct bigdatum {
char id[IDLEN+1]; // 0
/* and many other fields... */
};
static char *indexToId(int i) {
struct bigdatum x = Data[i]; // 1
char *result = x.id; // 2
return (result != NULL ? result : ""); // 3
}

At line one, you deep-copy the object Data[i] into x. However, x has a
lifetime that ends at the end of the function, and thus the pointer
result, that points to some data in x, and x is no more beyond line 3.

Quote:
My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?)

char-pointers? Which char-pointers? As you see in line 0, there is no
char-pointer, just an array.

Quote:
Then 'result' will be set equal
to that pointer and returned. Even when x goes out of existence,
isn't result pointing to the location I want?

Question is, what do you want? (-: It points to the first element
of the array id within x, and x is dead.

So long,
Thomas
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Keith Thompson
Guest





PostPosted: Mon Feb 19, 2007 9:27 am    Post subject: Re: question about auto struct variables Reply with quote

WillerZ <newsreplies (AT) willerz (DOT) plus.net> writes:
Quote:
mmcconnell17704 (AT) yahoo (DOT) com wrote:
I wrote this function to get the id of the i-th datum.
static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

That function is not valid in C, I assume you are using C++ and should
therefore ask this in a C++ group.
[...]


How so? I grabbed the code from the parent article, commented out a
line of English, added "#include <stddef.h>" for NULL, and it compiled
without error as C. I see nothing C++-specific.

--
Keith Thompson (The_Other_Keith) kst-u (AT) mib (DOT) org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Jorgen Grahn
Guest





PostPosted: Mon Feb 19, 2007 9:27 am    Post subject: Re: question about auto struct variables Reply with quote

On 16 Feb 2007 15:47:05 GMT, WillerZ <newsreplies (AT) willerz (DOT) plus.net> wrote:
Quote:
mmcconnell17704 (AT) yahoo (DOT) com wrote:
I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}

That function is not valid in C, I assume you are using C++ and should
therefore ask this in a C++ group.

In what way is it not valid? I see no obvious problem with it, and neither
does 'gcc -c -std=c89 -W -Wall -pedantic'.

Quote:
My question is, why is he right? Although x is a copy of Data[i], the
id fields of both objects should be char-pointers pointing to exactly
the same location (shouldn't they?)

No, id was declared as an inline array and not a pointer.

Correct; Data[i] has nothing to do with the problem, it has been copied
and is out of the picture. If the coworker claimed otherwise, don't take
advise from him/her in the future.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.dyndns.org> R'lyeh wgah'nagl fhtagn!
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
WillerZ
Guest





PostPosted: Mon Feb 19, 2007 10:40 pm    Post subject: Re: question about auto struct variables Reply with quote

Jorgen Grahn wrote:
Quote:
On 16 Feb 2007 15:47:05 GMT, WillerZ <newsreplies (AT) willerz (DOT) plus.net> wrote:
mmcconnell17704 (AT) yahoo (DOT) com wrote:
I wrote this function to get the id of the i-th datum.

static char *indexToId(int i) {
struct bigdatum x = Data[i];
char *result = x.id;
return (result != NULL ? result : "");
}
That function is not valid in C, I assume you are using C++ and should
therefore ask this in a C++ group.

In what way is it not valid? I see no obvious problem with it, and neither
does 'gcc -c -std=c89 -W -Wall -pedantic'.

For some reason, I thought you couldn't assign one struct to another.
But, as you point out, you can. Sorry about that...

Thanks Jorgen and Keith for pointing it out.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Douglas A. Gwyn
Guest





PostPosted: Thu Feb 22, 2007 10:11 am    Post subject: Re: question about auto struct variables Reply with quote

"WillerZ" <newsreplies (AT) willerz (DOT) plus.net> wrote in message
news:clcm-20070219-0005 (AT) plethora (DOT) net...
Quote:
For some reason, I thought you couldn't assign one struct to another. But,
as you point out, you can. Sorry about that...

Struct assignment and auto aggregate initialization were not supported
in many old C compilers.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Hans-Bernhard Bröker
Guest





PostPosted: Sun Feb 25, 2007 10:11 am    Post subject: Re: question about auto struct variables Reply with quote

Douglas A. Gwyn wrote:

Quote:
Struct assignment and auto aggregate initialization were not supported
in many old C compilers.

"Old" as in "of legal drinking age by now" (in quite a lot of
countries), that is.
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Jorgen Grahn
Guest





PostPosted: Thu Mar 29, 2007 6:22 am    Post subject: Re: question about auto struct variables Reply with quote

On 25 Feb 2007 09:13:57 GMT, Hans-Bernhard Bröker <HBBroeker@t-online.de> wrote:
Quote:
Douglas A. Gwyn wrote:

Struct assignment and auto aggregate initialization were not supported
in many old C compilers.

"Old" as in "of legal drinking age by now" (in quite a lot of
countries), that is.

[Very late response]

I have to admit that I still see people working around struct assignment
in new code -- people who probably were not programming in C in the
1980s. Typically they use memcpy() instead. Not sure exactly why --
maybe they learned from old, inherited copies of K&R?

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.dyndns.org> R'lyeh wgah'nagl fhtagn!
--
comp.lang.c.moderated - moderation address: clcm (AT) plethora (DOT) net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.