Re: [C] strcat() question

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 01/21/04


Date: Tue, 20 Jan 2004 18:57:05 -0500 (EST)


On Tue, 20 Jan 2004, thides wrote:
>

  My turn to be confusingly pedantic! ;-)

> "Martijn Lievaart" <m@remove.this.part.rtij.nl> wrote...
> > On Mon, 19 Jan 2004 21:25:07 -0500, thides wrote:
> > >
> > > That would be addresses cause each byte would fit into an address
> > > unless we are only talking about one byte.
> >
> > I'm not following you here.
>
> I am trying to say that each address holds (stores) one byte of data.

  At the machine level, yes, basically (depending on your definition
of "byte"). At the level of the C and C++ programming languages, no.
An "address" in C [or C++, but I'll just leave you to infer that from
now on] is just that -- a kind of a "street address" for an object
(i.e., a blob of bytes) that tells you *where to find* that object.
  Addresses do not "store" anything, any more than 123 Main Street
"stores" a house. 123 Main Street is an *address* that tells you
where to *find* a house, yes, but it's just an address. The house,
in C terms, is an "object," and it's not really "stored" anywhere
either -- it just *is* somewhere. When talking about C, I don't
use the term "stored" in any technical sense.

  Example [tell me if it's too difficult for you]:

struct FooStruct {
    int i;
    int j;
} foo;

  Now, 'foo' is an object. So are 'foo.i' and 'foo.j'. In the
street-addresses analogy, 'foo' is like an apartment complex, and
'foo.i' and 'foo.j' are like individual apartments in that building.
  '&foo' is the address of 'foo'. In fact, in my opinion it's a
little bit more than just an address, because '&foo' has a *type*;
it's of type 'pointer to FooStruct'.
  '&foo.i' is the address of 'foo.i', and has type 'pointer to int'.
Now, here's the interesting thing: This is the *same address* as
'&foo'! [The address of 'foo' is the same as the address of its
first member, guaranteed.] But in neither case do we see any 'bytes'
being involved on the C programming level: in one case, the thing
we find at that address is 'foo' (a FooStruct), and in another case,
we find 'foo.i' (an int).

  Maybe clearer: An 'address' tells you *where* to find something.
Add a type to that address, and that will tell you *what* you will
find. For example,

  void *p = &foo; /* p stores the address of 'foo' (and 'foo.i') */

  *(struct FooStruct *)p; /* Go find 'foo'! */
  *(int *)p; /* Go find 'foo.i'! */

> > At the machine level, there are no types. I should not have said integer
> > values, that was not correct. You have blobs of bytes that can represent
> > different things. It is up to the (assembly) programmer to apply the
> > correct machine instructions to the different blobs.
>
> Right and the compiler does this for you in C/C++ depending on the data
> type or instructions in the code.

  Right!

> > Contrast this with C or C++, where every blob of bytes has an assiociated
> > type. The programmer can only circumvent it by using a cast. Thi is
> > directly opposite to what happens at the machine level.
>
> So at the machine level there are no data types just address with values.

  Right, except that 'address' at the machine level means something
very subtly different [and so does 'value'], so here in this newsgroup
you should always assume we're talking about the C [or C++] meaning
of 'address', which is roughly "a description of where to find something."

> > I know I understood pointers much better once I
> > understood what happened on the machine level.
>
> I am hoping :)

  I agree with Martijn; however, I learned assembly language essentially
unconnected with C, so I really never got confused between machine-level
"pointers" and C pointers. If you just learn the machine-level stuff
separately, and then think about how C does what it does, rather than
trying to learn both at the same time, I think you'll do better.

> > > Ok we have a *p that is in one address and it points to the first
> > > address of the string which is a <space>
> >
> > No, it does not point to an address. The variable p stores [an]
> > address that points to a string. The expression *p is a space,
> > you've lost the pointer by dereferencing it.
>
> Ok got you. *p is the value.
> But I thought p stores [an] address that points to the address
> containing <space>

  Notice that I've fixed Martijn's typo, and yours ('n' for 'an').
I hope you weren't confused about that 'n'!
  Again, it's a problem of terminology. First of all, you can't
"point to" an address, any more than I can give you the street
address of "123 Main Street." You 'point to' an 'object'; I *can*
give you the street address of "Bob's house," which is the address
"123 Main Street."
  Secondly, it's not usual to say, "This address points to..." You
should say, "This is the address of..." or "This pointer points to..."
or "This pointer object contains the address of..." It's just the
way we say things in English.
  "*p is an expression that evaluates to <space>. p is a pointer
object that contains the address of the first character in the
string. p points to a character with the value <space>."

> Like if p was stored in address 0001 and <space> was stored in
> address 0003
> 0001 would contain the address 0003 (the value <space>)...

  Yes, except that by mixing it up with assembly-language notation,
you're... well... you're mixing it up. I would write the example
using real-world "data types" and the street-address metaphor:

  p is a house at 0001 Main Street.

  Taped to the refrigerator in p's kitchen is a note reading,
    "0003 Main Street."

  Taped to the microwave in the kitchen of the house at 0003
    Main Street is a note reading, "<space>."

Now, replace "house" by "blob of bytes."
Replace "Main Street" by "virtual memory space."
Replace "note reading 0003 Main Street" with "pointer with the
  'typeless integer' value 0003" -- that's what Martijn meant back
  there: 0003 is certainly an integer, but it's not supposed to
  be treated like one -- it's supposed to be a pointer. See how
  the "Main Street" analogy makes that more obvious?
Replace "note reading <space>" with "the value 0x20, or whatever
  typeless integer value your computer uses to represent the
  space character."
Replace "taped to the refrigerator" with "accessed as a pointer
  to char."
Replace "taped to the microwave" with "accessed as a char."

  I hope experts will notice all the little quirks this analogy
mimics; for example, suppose we write

  *(char*)&p;

That means, "Take the address of p, and access the blob of bytes
there as a char." So we go to 0001 Main Street and go into the
house and look on the microwave. Now, p doesn't have anything
taped to the microwave [or maybe it does, but it's nothing useful
to us]. So we've made a mistake, and we'll probably get demons
flying out of our noses because of it.
  [Yeesh, that was a mess. I should quit analogies.]

> Oh, brainwave... p would contain address 0003 to the /0 (string
> terminator) therefore the full string.

  I think you're wrong, but it's hard to tell what you mean.
p, the house at 0001 Main Street, has "0003 Main Street" taped
to its refrigerator.
  Let's suppose we call 'puts(p)'. So, let's take this one step
at a time and see how the string gets to our screen.

  Evaluate p. (We enter the house, access the refrigerator, and
find the note. "0003 Main Street." Good.)
  Pass that value to 'puts'. (Call up the skywriter and tell him,
"0003 Main Street" -- the value we got from 'p'. He'll know what
to do.)
  'puts' gets called. (The skywriter gets out his little rulebook
and follows his directions. His directions say, "You have been
given an address. Go to that house and look on the microwave.
Write what you see. Go to the next house [in this case, 0004
Main Street] and repeat the process. Stop only when you find a
microwave with the null character taped to it.")
  (So the skywriter goes to 0003 Main Street, accesses the microwave,
and writes <space>. He goes to 0004 Main Street and writes 'w'.
Then 'o' and 'r' and 'l' and 'd', and then he gets to the house
at 0009 Main Street and finds the null character taped to the
microwave. So he stops.)
  (Then the skywriter telephones us back and says, "All done writing;
it's your turn again." And on we go.)

  Notice that if we made a mistake and wrote

  puts(&p);

the skywriter would have gone to 0001 Main Street (the address of
p) instead of 0003 Main Street (the value p contains). And he
would have found garbage on the microwave, and been really confused.
That's called "undefined behavior," and it's bad.

> > >> That is why we have
> > >> high level languages, so we can deal with concepts instead of bits).
> > >
> > > I dont think we store things in just bits in the address I think
> > > it is in bytes.

  Bytes are just blobs of bits. Your statement is like you're
saying that the English language doesn't use letters, it uses words.
It's basically the same thing, from our point of view. Bits and bytes
are just places to keep information.

> I was thinking that an address is a byte. Maybe at machine language we
> can store things in certain bits but in C/C++ the smallest data type is
> a char which size is equal to a byte.

  Machine-level addresses are almost always multi-byte. In C and C++,
pointers are almost always multi-byte objects, too. And you *can*
store things in single bits in C and C++; look up "bit-fields."
However, you cannot take the address of a bit-field, so it's not
an object; kind of like you can keep things in different rooms in
your house, but you can't write down the street address of your
kitchen or your bedroom. :)

> Am I getting the idea?

  Slowly and in pieces, yes, certainly. Keep it up!

HTH,
-Arthur



Relevant Pages

  • Re: Shop Wall and Electric
    ... I suspect two things - have to get my scope in the house. ... The switcher that generates the power needed from high voltage to low current. ... I used microwave ovens at work in 1968. ... recepticals could be on the same circuit and 2,4&6 on your counter could be ...
    (rec.woodworking)
  • Re: RMD User Map
    ... set up the one for STP. ... My pointer is not ... Normally, I don't keep bikes at the house, unless they are in the ... '06 Gas Gas DE300 ...
    (rec.motorcycles.dirt)
  • Re: Declaring static pointers.
    ... a pointer to my house might be: ... However, in the current context, we refer to an address in memory, ... ROM and RAM might exist in completely different ...
    (comp.lang.c)
  • Re: RMD User Map
    ... I just put my pointer on Smackover. ... northwest of the house.) ... I had 12.5 miles of tight single track "workout trail" ... '06 Gas Gas DE300 ...
    (rec.motorcycles.dirt)
  • Re: My cats might get the feed of their life tomorrow!
    ... I microwaved it and the smell made me retch and nearly vomit. ... My house absolutely stinks of bad fish. ... Boil some lemon juice in water in the microwave. ...
    (rec.pets.cats.anecdotes)