 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Tue Feb 13, 2007 6:22 pm Post subject: question about auto struct variables |
|
|
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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables[c.l.c.moderated] |
|
|
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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables [comp.lang.c.modera |
|
|
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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables |
|
|
<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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Fri Feb 16, 2007 9:47 pm Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Mon Feb 19, 2007 9:27 am Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Mon Feb 19, 2007 9:27 am Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Mon Feb 19, 2007 10:40 pm Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Thu Feb 22, 2007 10:11 am Post subject: Re: question about auto struct variables |
|
|
"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
|
Posted: Sun Feb 25, 2007 10:11 am Post subject: Re: question about auto struct variables |
|
|
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
|
Posted: Thu Mar 29, 2007 6:22 am Post subject: Re: question about auto struct variables |
|
|
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 |
|
 |
|
|
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
|
|