473,545 Members | 1,863 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Help the helpless.. code read

I've been programming for many years, but have only recently taken a
deep "C" dive (bad pun, i know) and need a lot of explanation from an
expert. My questions center around those mysterious pointer beasties.

The following code is excerpted from digitemp, a program that reads
1-wire devices. Digitemp is the work of Brian C. Lane.

As I walk through this code, I have a number of questions. I'm hoping
someone with experience in pointers can provide a few for me (another
pun) :) Also, I am sorry that this message is long. I tried to
shorten it, but could not get my questions across any other way.

I have indented the code and my questions and comments are preceded by
// so they will be easier to follow. I hope this is less confusing and
respectful of everyone's time.
// The following _roms structure contains a list of 8 byte addresses...

struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};

// A variable, sensor_list is initialized...

struct _roms *sensor_list

// The roms part of the structure is filled with an "array" of sorts,
// containing one or more 8-byte addresses. These addresses resolve,
// when printed, as hex values.

// For example: "12BAA91C000000 A3" is a valid address string.

// The other variable within the _roms structure is "max" which is
// loaded with the total number of addresses stored in "roms".

// As I understand it, *sensor_list as defined above is a pointer to the
// beginning of the entire structure defined as _roms.

// Is this correct?
// Let's say sensor_list is loaded with one 8-byte-wide address:
// "12BAA91C000000 A3".

// Here is how it's passed through in the code:

read_all(&senso r_list);

// Above, read_all(&senso r_list) says "call the read_all function and
// pass as a parameter the (starting) address where the variable
// sensor_list is. Is this a correct reading?

int read_all(struct _roms *sensor_list)
{
int x;
for(x = 0; x < (num_cs + sensor_list->max); x++)
{
read_device(sen sor_list, x);
}
return 0;
}

// It appears that a de-referenced pointer to sensor_list is being
// defined in the function header, correct? (Since the address of
// sensor_list was passed in the call to read_all(&senso r_list).)

// From this, is it correct to assume that further de-referencing of
// sensor_list will not be needed?

// Here's where the action takes place:

int read_device(str uct _roms *sensor_list, int sensor)
{
...
}

// What seems odd to me is that, again, sensor_list is being defined in
// this function header as a dereferenced pointer. Yet, the calling
// function used a variable (sensor_list) that had already been
// de-referenced. That's why it called read_device with just
// "sensor_lis t", correct?

// So there is a fundamental here that I am not understanding.

// Within read_device, the sensor_list structure is used to pass a
// complete 8-byte address to a function called owSerialNum:

owSerialNum( 0, &sensor_list->roms[sensor*8], FALSE );

// If I call the function like this:

owSerialNum( 0, "12BAA91C000000 A3", FALSE );

// it works perfectly. The documentation for owSerialNum says that the
// second parameter is a buffer containing the address.

// I can see that &sensor_list->roms[sensor*8] is saying, "the address
// of roms[beginning at this offset] within a structure we call
// "sensor_lis t".

// Since the second parameter in
// owSerialNum( 0,"12BAA91C0000 00A3",FALSE); is passed through as the
// starting address of a buffer, and since &sensor_list->roms[sensor*8]
// is also the address of a buffer, they must be synonymous, correct?

// Well, they appear not to be so.
// The following code works:

printf(" Address: %s","12BAA91C00 0000A3");

// This prints garbage:

printf(" Address: %s",&sensor_lis t->roms[sensor*8] );

// In fact, it looks like it's printing a memory address instead of the
// contents of that address. Why?

// If I do this...

printf("Sensor here: %s\n",sensor_li st->roms[sensor*8]);

// I get a segmentation fault (crash).
// If I do this:

printf("Sensor here: %s\n",*sensor_l ist->roms[sensor*8]);

// The compiler complains: invalid type argument of `unary *'
*********

What I eventually want to do is pass into the application an address as
a string parameter, and be able to pass it into the read_device
function so that it is properly passed to owSerialNum(). It seems
simple enough, but I'm hung up on the above issues at the moment. If I
can be guided through the mud, this once, I think I'll have it.
Help!

Nov 14 '05 #1
19 2059
Mark Richards wrote:
.... snip ...
I have indented the code and my questions and comments are
preceded by // so they will be easier to follow. I hope this is
less confusing and respectful of everyone's time.

// The following _roms structure contains a list of 8 byte
addresses...

struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};


Let's stop right there, as the rest of the assumptions will be
wrong. roms is a pointer to an unsigned char. It is not an array
of any sort. I read no further.

In addition the identifier '_roms' is reserved for the
implementation. You should not be using it. Such use may cause
undefined behaviour.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #2
Mark Richards wrote:
I've been programming for many years, but have only recently taken a
deep "C" dive (bad pun, i know) and need a lot of explanation from an
expert. My questions center around those mysterious pointer beasties.
I'll tackle a small portion of your question.
// The following _roms structure contains a list of 8 byte addresses...

struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};

// A variable, sensor_list is initialized...

struct _roms *sensor_list
Registered. Although this line is not valid C as it stands. It
needs a semi-colon as termination, possibly preceded by an
actual initialization.
// As I understand it, *sensor_list as defined above is a pointer to the
// beginning of the entire structure defined as _roms.
Not quite: sensor_list is declared as having the type, "pointer to
struct _roms". "*sensor_li st", that is the thing you get when you
dereference sensor_list, then has type struct _roms.
// Here is how it's passed through in the code:

read_all(&senso r_list);
// Above, read_all(&senso r_list) says "call the read_all function and
// pass as a parameter the (starting) address where the variable
// sensor_list is. Is this a correct reading?
Yes, it's correct.
int read_all(struct _roms *sensor_list)


Stop right there. Unless there's some slippage in your quotation
from the original C source, this is an error. "sensor_lis t" was
of type "pointer to struct _roms". The thing you get by writing
"&sensor_li st" is then of type "pointer to pointer to struct _roms",
or struct _roms **. And this is not compatible with the stated
parameter type for read_all().

Allin Cottrell
Wake Forest University
Nov 14 '05 #3
> In addition the identifier '_roms' is reserved for the
implementation. You should not be using it. Such use may cause
undefined behaviour.
When you say it's reserved for the implementation, do you mean that it's
possibly a reserved word, or that the underscore should not be used?
roms is a pointer to an unsigned char.

If I define:

struct _roms *sensor_list

then the variable sensor_list acts as a pointer to the structure, correct?


CBFalconer wrote: Mark Richards wrote:

... snip ...
I have indented the code and my questions and comments are
preceded by // so they will be easier to follow. I hope this is
less confusing and respectful of everyone's time.

// The following _roms structure contains a list of 8 byte
addresses...

struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};

Let's stop right there, as the rest of the assumptions will be
wrong. roms is a pointer to an unsigned char. It is not an array
of any sort. I read no further.

Nov 14 '05 #4
Mark Richards wrote:
> In addition the identifier '_roms' is reserved for the
> implementation. You should not be using it. Such use may cause
> undefined behaviour.


When you say it's reserved for the implementation, do you mean that it's
possibly a reserved word, or that the underscore should not be used?


Sufficiently many identifier-like things beginning with _ are reserved
to the implementation that the easiest rule to remember is "don't use
them".

The implementation is free to attach any meaning it pleases to such
words. (I can't remember whether it's obliged to document those
meanings.) In particular it may use them as struct tags for its own
structures such as might be hidden in #include files.
>>roms is a pointer to an unsigned char.

If I define:

struct _roms *sensor_list

then the variable sensor_list acts as a pointer to the structure, correct?


The variable sensor_list, when its value is required, should either be
the null pointer or point to an object of type struct _roms (which may be
the first of several such contiguous objects, of course).

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgrou...mp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambl...me_to_clc.html
Nov 14 '05 #5
Allin,
Stop right there. Unless there's some slippage in your quotation
from the original C source, this is an error. "sensor_lis t" was
of type "pointer to struct _roms". The thing you get by writing
"&sensor_li st" is then of type "pointer to pointer to struct _roms",
or struct _roms **. And this is not compatible with the stated
parameter type for read_all().
Here's how it's initialized (I've removed extraneous code):

int main(int argc, char *argv[])
{
...
struct _roms sensor_list; /* Attached Roms */
...

if(read_rcfile( conf_file, &sensor_list ) < 0);
...
// later on in main():

read_all(&senso r_list);


int read_rcfile(cha r *fname, struct _roms *sensor_list)
...
sensor_list->roms = malloc(sensors * 8);
sensor_list->max = sensors;

for(x = 0; x < 8; x++)
{
ptr = strtok(NULL, " \t\n");
sensor_list->roms[(sensors * 8) + x] = strtol(ptr, (char **) NULL, 0);
}

-------------------

Indeed, the call read_all(&senso r_list); is being made.

So...

This:
struct _roms sensor_list; /* Attached Roms */

initializes the variable sensor_list which, when referenced, is a
pointer to the start of the structure...

and this:
if(read_rcfile( conf_file, &sensor_list ) < 0);

passes that pointer (of sensor_list) to read_rcfile. If instead it read
sensor_list, then the variable would be passed by value, correct?

and this:

int read_rcfile(cha r *fname, struct _roms *sensor_list)

says that the incoming variable *sensor_list is the address of the
variable sensor_list?

and this:

read_all(&senso r_list);

says to pass the address of sensor_list (not a pointer address) to read_all?

I'm trying to follow the state of sensor_list from initialization. Here
are my assumptions:
struct _roms sensor_list; -> a block of memory defined by the
width of _roms is allocated and
sensor_list is assigned to reference
it;

if(read_rcfile( conf_file, &sensor_list ) < 0);
-> the address of sensor_list is passed
into read_rcfile. Oops. I thought
sensor_list was the address;

int read_rcfile(cha r *fname, struct _roms *sensor_list);
-> sensor_list is now a pointer to the
new structure;

sensor_list->roms
-> the use of sensor_list is now
assumed to be a pointer, since the
function typedef was *sensor_list.
I assume that referencing it like
this would be illegal:

struct _roms sensor_list;
sensor_list->roms (...

It must be done thusly?
*sensor_list->roms (...

Now, back in main():

read_all(&senso r_list);
-> So the address of the address is
being stated here? That does seem
strange. However, this is the
original unmodified code, that works.

As my wife is loathe to say, I'm clearly missing a fundamental here.
-m-


Allin Cottrell wrote:
Mark Richards wrote:
I've been programming for many years, but have only recently taken a
deep "C" dive (bad pun, i know) and need a lot of explanation from an
expert. My questions center around those mysterious pointer beasties.

I'll tackle a small portion of your question.
// The following _roms structure contains a list of 8 byte addresses...

struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};

// A variable, sensor_list is initialized...

struct _roms *sensor_list

Registered. Although this line is not valid C as it stands. It
needs a semi-colon as termination, possibly preceded by an
actual initialization.
// As I understand it, *sensor_list as defined above is a pointer to the
// beginning of the entire structure defined as _roms.

Not quite: sensor_list is declared as having the type, "pointer to
struct _roms". "*sensor_li st", that is the thing you get when you
dereference sensor_list, then has type struct _roms.
// Here is how it's passed through in the code:

read_all(&senso r_list);



// Above, read_all(&senso r_list) says "call the read_all function and
// pass as a parameter the (starting) address where the variable
// sensor_list is. Is this a correct reading?

Yes, it's correct.
int read_all(struct _roms *sensor_list)

Stop right there. Unless there's some slippage in your quotation
from the original C source, this is an error. "sensor_lis t" was
of type "pointer to struct _roms". The thing you get by writing
"&sensor_li st" is then of type "pointer to pointer to struct _roms",
or struct _roms **. And this is not compatible with the stated
parameter type for read_all().

Allin Cottrell
Wake Forest University

Nov 14 '05 #6
Mark Richards wrote:
In addition the identifier '_roms' is reserved for the
implementation. You should not be using it. Such use may cause
undefined behaviour.


When you say it's reserved for the implementation, do you mean
that it's possibly a reserved word, or that the underscore should
not be used?


Please do not toppost. Please do snip non-germane quoted portions.

It is not a reserved word - those are completely specified in the
standard. However the implementation may use identifiers with
leading underscores freely, and is quite likely to do so in the
system headers. The way to avoid clashes is to avoid using such
identifiers.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #7
> Please do not toppost. Please do snip non-germane quoted portions.
Sorry. Will do.
The way to avoid clashes is to avoid using such
identifiers.

Thanks for the clarification.

-m-
Nov 14 '05 #8
Mark Richards wrote:
Allin,
> Stop right there. Unless there's some slippage in your quotation
> from the original C source, this is an error. "sensor_lis t" was
> of type "pointer to struct _roms". The thing you get by writing
> "&sensor_li st" is then of type "pointer to pointer to struct _roms",
> or struct _roms **. And this is not compatible with the stated
> parameter type for read_all().
Here's how it's initialized (I've removed extraneous code):

int main(int argc, char *argv[])
{
...
struct _roms sensor_list; /* Attached Roms */


Ah, we're OK then: "sensor_lis t" is an actual instance of struct
_roms, not a pointer to same. So when you take the address:

&sensor_list

you get something of type "struct _roms *", or pointer-to-struct-
_roms, which is an acceptable parameter to the function read_all(),
cited earlier.
So...

This:
struct _roms sensor_list; /* Attached Roms */

initializes the variable sensor_list which, when referenced, is a
pointer to the start of the structure...
....which, when one takes its address, yields a pointer to the
structure ("start of" is kinda redundant).
and this:
if(read_rcfile( conf_file, &sensor_list ) < 0);

passes that pointer (of sensor_list) to read_rcfile. If instead it read
sensor_list, then the variable would be passed by value, correct?
The function read_rcfile() would in that case get a "local copy" of
the structure, and the struct in the caller would remain unmodified,
contrary to the programmer's intention, Yes.
and this:

int read_rcfile(cha r *fname, struct _roms *sensor_list)

says that the incoming variable *sensor_list is the address of the
variable sensor_list?
Yup.
and this:

read_all(&senso r_list);

says to pass the address of sensor_list (not a pointer address) to
read_all?
The address of a struct (and hence a pointer-to-struct), but not the
address of a pointer, no.
I'm trying to follow the state of sensor_list from initialization. Here
are my assumptions:

struct _roms sensor_list; -> a block of memory defined by the
width of _roms is allocated and
sensor_list is assigned to reference
it;
Yes.
if(read_rcfile( conf_file, &sensor_list ) < 0);
-> the address of sensor_list is passed
into read_rcfile. Oops. I thought
sensor_list was the address;
Your current thought is correct.
int read_rcfile(cha r *fname, struct _roms *sensor_list);
-> sensor_list is now a pointer to the
new structure;
Within the function read_rcfile(), sensor_list figures as
a pointer-to-struct, not a struct "in person", yes.
sensor_list->roms
-> the use of sensor_list is now
assumed to be a pointer, since the
function typedef was *sensor_list.
"typedef" is not the term you want here. The parameter was
declared to be of type "pointer to struct _roms".
I assume that referencing it like
this would be illegal:

struct _roms sensor_list;
sensor_list->roms (...
Yes, if the parameter to the function were of type struct _roms,
you would get a compiler error on using the syntax

sensor_list->roms ...
It must be done thusly?
*sensor_list->roms (...
Huh? If the parameter (counter-factually) had been,
struct _roms sensor_list, then you'd do things like

sensor_list.rom s = ...

(In your example, the prepended "*" doesn't make the invalid
"->" any less invalid.)
Now, back in main():

read_all(&senso r_list);
-> So the address of the address is
being stated here?


No, I fear you have lost the place. Up above, you had "sensor_lis t"
as of type plain "struct _roms" in main.

Allin Cottrell
Wake Forest University
Nov 14 '05 #9
Mark Richards <no****@massmic ro.com> wrote in message news:<40******* *************** *@news.newshost ing.com>...

<snip>
[...]My questions center around those mysterious pointer beasties.
find a good book. "The C Programming Language" by Kernighan and Richie
explains pointers quite well.

<snip>
// The following _roms structure contains a list of 8 byte addresses...
as others have noted, no it doesn't.

struct _roms
{
unsigned char *roms; /* Array of 8 bytes */
int max; /* Maximum number */
};

// A variable, sensor_list is initialized...

struct _roms *sensor_list
else-thread you change this to

struct _roms sensor_list;

<snip>
read_all(&senso r_list);

// Above, read_all(&senso r_list) says "call the read_all function and
// pass as a parameter the (starting) address where the variable
// sensor_list is. Is this a correct reading?
call the read_all function with a pointer to the sensor_list struct.
If you like you use "address" instead of "pointer". On a typical
implementation pointers will be addresses.

int read_all(struct _roms *sensor_list)
{
int x;
for(x = 0; x < (num_cs + sensor_list->max); x++)
{
read_device(sen sor_list, x);
}
return 0;
}

// It appears that a de-referenced pointer to sensor_list is being
// defined in the function header, correct?
no. sensor_list is a pointer to struct _roms. This is the source of
confusion to beginning C programmers. * is used in two different ways
(well three if you count multiplication) .

int *a;

a is ptr to int

*a = 1;

a is being dereferenced. a is still a pointer to int but *a is an int.
Another way of looking at it that

int *a;

declares *a to be an int. Usage mirrors declaration syntax. Opinions vary
as to whether this was a good idea.

<snip>
// Within read_device, the sensor_list structure is used to pass a
// complete 8-byte address to a function called owSerialNum:

owSerialNum( 0, &sensor_list->roms[sensor*8], FALSE );
why did you multiply by 8?
why did you take the address?
Try:-

owSerialNum (0, sensor_list->roms [sensor], FALSE;

(assuming you've initialised roms correctly)
// If I call the function like this:

owSerialNum( 0, "12BAA91C000000 A3", FALSE );

// it works perfectly. The documentation for owSerialNum says that the
// second parameter is a buffer containing the address.

// I can see that &sensor_list->roms[sensor*8] is saying, "the address
// of roms[beginning at this offset] within a structure we call
// "sensor_lis t".
yes, but roms is a pointer to unsigned char, why take its address?

// Since the second parameter in
// owSerialNum( 0,"12BAA91C0000 00A3",FALSE); is passed through as the
// starting address of a buffer, and since &sensor_list->roms[sensor*8]
// is also the address of a buffer, they must be synonymous, correct?


nope.

<snip>
--
Nick Keighley

You are in a clearing. You can see a spire in the distance.
You can also see a copy of "C Unleashed".
: INV
You have;
a DeathStation 900 laptop,
a voucher for a free pizza,
and a torch.
: TAKE BOOK
You can't. It's too heavy.
Bill Godfrey (clc)
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

46
5098
by: Kingdom | last post by:
In my data base I have a list of componet types e.g. type A - I have 8 off - type B I have 12 off etc. I'm using Set objRS = objDC.Execute("Select DISTINCT Component_Type FROM Parts_Table") to populate a drop down but would like to use several drop downs restricting the contents of each drop down to the records pertaining to one
1
1855
by: chaoticseed | last post by:
Alright, honestly ive been programming for about 1 year within the last 4 or 5 years so im not helpless!!! Ive never been able to get a good c++ compiler until now!!! I just got microsoft visual c++, and am having troubles. Im on the first tutorial and this is the gist of it. ...
5
6331
by: Tamar | last post by:
Hello all, I am so frustrated. I am doing something so simple and yet I confront such a problem. I am writing a program in VB, opening a db connection to an access db using ADODC control. I disply a record's fields and I can navigate through the recordset. BUT when trying to change a field content or when adding a new record I receive the...
1
1518
by: Capt_Ron | last post by:
Hello and thank you for taking the time to look. I Have a form that asks for options. I need the user to click any of the options listed. I'd like to use the CheckedListBox for this but I need to know how it works. I have the options in a table in a database. I would like to have the datasource of the CheckedListBox be a datareader...
1
1546
by: gilbert.havlik | last post by:
Greetings! Please be so kind and take a few minutes, I believe any mind other than mine can solve this. I am writing a game. As you wander through the gameworld, you may come upon signs. I have a DB where the signs are listed, with "longitude" and "latitude". Anytime someone takes a step, I want to show a grid where any square can be...
10
3338
by: JonathanOrlev | last post by:
Hello everybody, I wrote this comment in another message of mine, but decided to post it again as a standalone message. I think that Microsoft's Office 2003 help system is horrible, probably the worst I ever seen. I almost cannot find anything I need, including things I
4
1237
by: tirumalab | last post by:
if i enter the value in my textbox(edit_mobileno) i want to search for the matching and i want to read all the xmlelements in that perticular<customer></customer> tag... see below for myxml file... XmlTextReader xr = new XmlTextReader(@"D:\Newfolder\tirumala\myxml.xml"); while (xr.Read()) { if...
1
1016
by: =?Utf-8?B?WGl1a2Vvbmc=?= | last post by:
Hi there, i am a novice in getting my c++/clr work for my final year project. may i know where or how can i get information about calling a second form from the first form ? i being looking for quite sometime but all seems helpless for me.thanks for advance ..
53
8332
by: souporpower | last post by:
Hello All I am trying to activate a link using Jquery. Here is my code; <html> <head> <script type="text/javascript" src="../../resources/js/ jquery-1.2.6.js"</script> <script language="javascript" type="text/javascript">
0
7487
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7934
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7446
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6003
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4966
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3476
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3459
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1908
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1033
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.