where are the strings?

T

Thomas Zhu

Hello,

I know the difference between the two definations.
But I do not know where are they in the memory.
would someone tell me ?

char s[][10]={"good", "morning"}; // at stack?
char *t[] = {"good", "morning"}; // at heap?

thanks in advance.
 
W

Walter Roberson

I know the difference between the two definations.
But I do not know where are they in the memory.
would someone tell me ?
char s[][10]={"good", "morning"}; // at stack?
char *t[] = {"good", "morning"}; // at heap?

Standard C does not know anything about stacks or heaps.

The only distinction in C is whether a variable is static,
auto, or register.

Based upon previous postings, I gather that there are real C
compilers out there for implementations which do not use stacks
or heaps.
 
C

Christopher Benson-Manica

Thomas Zhu said:
I know the difference between the two definations.
But I do not know where are they in the memory.
would someone tell me ?
char s[][10]={"good", "morning"}; // at stack?
char *t[] = {"good", "morning"}; // at heap?

The answer here is "We don't know" - it's wholly dependent on your
implementation. However, the strings in the second definition are
likely to end up in a different place than the first; string literals
may well be stored in a special area of memory, which may or may not
be read-only (and you may not modify them, in either case).
 
N

Neil Cerutti

Hello,

I know the difference between the two definations.
But I do not know where are they in the memory.
would someone tell me ?

char s[][10]={"good", "morning"}; // at stack?
char *t[] = {"good", "morning"}; // at heap?

thanks in advance.

The important difference between the two examples is that the
former's strings will be modifiable, while the latter's will not.
 
J

Jordan Abel

I know the difference between the two definations.
But I do not know where are they in the memory.
would someone tell me ?
char s[][10]={"good", "morning"}; // at stack?
char *t[] = {"good", "morning"}; // at heap?

Standard C does not know anything about stacks or heaps.

The only distinction in C is whether a variable is
static,

For which as a convenience we can use the term "data"

ditto "stack"
or register.

and "register" will do just fine for this

and you forgot malloc - which is what "heap" generally means.
Based upon previous postings, I gather that there are real C
compilers out there for implementations which do not use stacks
or heaps.

Now, in actual answer for his question, that depends on where you
declare this - the string data will be in automatic storage [aka
"stack"] in the first case if declared in a function, or in static
storage if you declared it at the top level of the file. In the
second case, these are string literals and will often be stored in a
nonwritable segment.
 
A

Alan Balmer

For which as a convenience we can use the term "data"

Why is that more "convenient" than "static"? Especially when it
doesn't mean the same thing?
ditto "stack"
Also no more convenient and much less accurate.
and "register" will do just fine for this
Thank you ;-)
and you forgot malloc - which is what "heap" generally means.
Based upon previous postings, I gather that there are real C
compilers out there for implementations which do not use stacks
or heaps.

Now, in actual answer for his question, that depends on where you
declare this - the string data will be in automatic storage [aka
"stack"] in the first case if declared in a function, or in static
storage if you declared it at the top level of the file. In the
second case, these are string literals and will often be stored in a
nonwritable segment.

No, the actual answer to his question is "It depends. You should ask
in a newsgroup which knows the answer for whatever implementation you
are using." This could be followed by the (on-topic) statement that
"In most cases, you shouldn't care where it's stored. You should only
care that one form is modifiable, and the other is not."
 
J

Jordan Abel

On 2005-10-27 said:
Thank you ;-)

As long as everyone understands that they're not _really_ registers.
Now, in actual answer for his question, that depends on where you
declare this - the string data will be in automatic storage [aka
"stack"] in the first case if declared in a function, or in static
storage if you declared it at the top level of the file. In the
second case, these are string literals and will often be stored in
a nonwritable segment.

No, the actual answer to his question is "It depends. You should
ask in a newsgroup which knows the answer for whatever
implementation you are using." This could be followed by the
(on-topic) statement that "In most cases, you shouldn't care where
it's stored. You should only care that one form is modifiable, and
the other is not."

And no-one but me actually told him the part about one being
non-modifiable
 
P

Peter Nilsson

[highly edited...]

Jordan said:
register

and... malloc - heap

Can you tell me why you think that understanding an alternative
paradigm to the standard is important? Particularly when writing code
that is to be maximally portable?

Your response seems typical of people who learn unix or windows
specific programming, and who now seem unable, or at least unwilling,
to actually understand the C language in its own terms.

I've don't understood why specific alternatives are actually
useful! They tend to lead to misunderstandings, in the same way
that people trying to learn C by reading compiler disassemblies
are often confused when they start programming on a different
architectures. It's usually because they started with preconceptions
that, whilst supported within the C language, needn't (and often
don't) apply to different implementations.

Something as simple as focusing on _when_, rather than _where_
objects are stored, is considerably more useful and leads to much
less confusion in the long term (in my experience).
... string literals ... will often be stored in a nonwritable
segment.

Classic example...

This means nothing to someone programming an old mac that doesn't
use anything called a segment. And I can't see why this ostensibly
priceless nugget of information is somehow more relavent than...

"Modifying string literals invokes undefined behaviour."

The latter being applicable to _any_ implementation of the virtual
C machine.

Fundamentally, I'm asking you: why confuse people with
specialisations when the abstraction is straight forward enough,
and more useful?
 
J

Jordan Abel

Can you tell me why you think that understanding an alternative
paradigm to the standard is important? Particularly when writing code
that is to be maximally portable?

Your response seems typical of people who learn unix or windows
specific programming, and who now seem unable, or at least unwilling,
to actually understand the C language in its own terms.

I've don't understood why specific alternatives are actually
useful! They tend to lead to misunderstandings, in the same way
that people trying to learn C by reading compiler disassemblies
are often confused when they start programming on a different
architectures. It's usually because they started with preconceptions
that, whilst supported within the C language, needn't (and often
don't) apply to different implementations.

Something as simple as focusing on _when_, rather than _where_
objects are stored, is considerably more useful and leads to much
less confusion in the long term (in my experience).

I think you misunderstand the use of the terms by unix/windows
programmers - i, for example learned "the heap" as a generic term
for malloc-space, years before i learned about the data structure
called a heap. They're just words.
Classic example...

This means nothing to someone programming an old mac that doesn't
use anything called a segment.

Neither does my own freebsd system as far as i know [iirc what i am
thinking of are called "sections" on most modern unixes] - it's just
a word.
And I can't see why this ostensibly
priceless nugget of information is somehow more relavent than...

"Modifying string literals invokes undefined behaviour."

Yes, but you didn't say that. I came closer to you than saying that
initially.

Let's define "nonwritable" as "that which an attempt to write to
will either be guaranteed to fail or cause undefined behavior", and
"segment" as any area of memory. There's hardly any more relevant
meaning of those terms that applies to the "C virtual machine" [i
assume you meant 'abstract', not 'virtual']
 
C

Chris Torek

You are perhaps better off not knowing, in many cases. :)
char s[][10]={"good", "morning"}; // at stack?
char *t[] = {"good", "morning"}; // at heap?

The important difference between the two examples is that the
former's strings will be modifiable, while the latter's will not.

This is indeed an important difference, but not necessarily
the only one. In particular, the code fragments above might
be incomplete, so that the above is not the entire translation
unit.

Consider the following (complete-program) translation unit:

#include <stdio.h>

char a[] = "hello";
char *b = "world";

char *e(int x) {
return x ? a : b;
}

char *f(int x) {
char c[] = "cello";
char *d = "whorl";

return x ? c : d;
}

int main(void) {
printf("%s %s\n", e(1), e(0));
printf("%s\n", f(0));
return 0;
}

The behavior and output of this program is well-defined, but if
one were to change the second printf() to call f(1), the program
would have undefined behavior and the output would be unpredictable.
On many implementations, the second line of output will contain
some sort of trash, as in the one I used to run it here:

% ./t
hello world
ÜzÓ
/<invalid character deleted>¬z`

The reason for the undefined behavior is that the string in
the array named "c" has automatic duration, lasting only as
long as the array object itself. The array is (at least in
principle) destroyed when f() returns, and on this implementation,
by the time printf() gets around to using the pointer, the
array is in fact destroyed (hence the u-umlaut and so on).

When a string literal is used to initialize an array object, the
characters in the literal simply initialize that object. The scope
and duration of the object are not affected by the string literal.

On the other hand, when a string literal appears in some other
context, its characters are used to initialize an anonymous array
that is -- at least in principle -- read-only, yet nonetheless has
type "array N of char" -- not "array N of const char", even though
"const" would make sense -- where N is the number of "char"s required
to contain the whole literal plus an additional terminating '\0'
byte. Hence, in the code above, "world" and "whorl" both initialize
anonymous objects of type "array 6 of char". The objects so
initialized have static duration, so they last as long as the
program runs (and possibly beyond then; the C Standards sayeth not)
and no scope (they are anonymous, so the concept of scope does not
really apply).

Thus, to go back to the original examples:
char s[][10]={"good", "morning"}; // at stack?

The Standards do not define "a" (much less "the") stack, although
automatic variables behave in a stack-like manner, and a single
stack, or sometimes two stacks -- one for data and one for control
-- are quite common. But if "s" is outside any function, the
variable s is not going to be on the data-stack in typical
implementations; if it is inside a function, it is. In
any case, the type of "s" will be "array 2 of array 10 of char"
and the memory contents can be described pictorially as:

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-...-+
| g | o | o | d |\0 |\0 |\0 |\0 |\0 |\0 | m | o | r | n | ... |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-...-+

The scope and duration of "s" will be the same as that of
any other variable not declared with "static" or "extern",
i.e., depends on whether s is declared within a function.
char *t[] = {"good", "morning"}; // at heap?

In this case, the answer is more complex. Once again, the Standards
do not define the term "heap"; but if we take that word to mean
"the space that malloc() allocates, and free() destroys", the answer
is: no, none of these will be in that space.

Instead, the string "good" will initialize some anonymous array
of type "array 5 of char":

+---+---+---+---+---+
| g | o | o | d |\0 |
+---+---+---+---+---+

This array will live somewhere in memory, possibly in read-only
memory, and will be present and initialized by the time main() is
entered initially; the array will still exist up until the program
exits (and possibly afterward, or perhaps not; as far as the Standard
is concerned, the "program universe" vanishes once the program
exits, and no one cares anymore).

The string "morning" will initialize some other anonymous array,
perhaps somewhere near the one that contains "good\0", perhaps not:

+---+---+---+---+---+---+---+---+
| m | o | r | n | i | n | g |\0 |
+---+---+---+---+---+---+---+---+

This object has type "array 8 of char" and again may (or may not)
be read-only.

Finally, the ordinary variable "t" will be created, with type
"array 2 of pointer to char", initialized so that t[0] points
to the first anonymous object, and t[1] to the second:

+---+---+---+---+---+
_--> | g | o | o | d |\0 |
/ +---+---+---+---+---+
|
|
+-------+-------+
| * | * |
+-------+-------+
|
___________/
/
|
\ +---+---+---+---+---+---+---+---+
`-> | m | o | r | n | i | n | g |\0 |
+---+---+---+---+---+---+---+---+

The duration and scope of the object named "t" will be the same as
that of "s", assuming both are inside (or both outside) a function.

It is possible (but not necessarily the case) that the strings
"good\0" and "morning\0" will actually abut in memory.

If it were important that they did, one could write:

static char strpair[] = "good\0morning";

to initialize a named (non-anonymous) array, give it static duration,
make it read/write (or add "const" to make it read-only), and then
use &strpair[0] instead of "good" and &strpair[5] instead of
"morning". Or one could write, e.g.:

void f(void) {
char *t[2];

t[0] = "good\0morning";
t[1] = t[0] + 5;
... code ...
}

Note that embedded \0 sequences in string literals are copied
through to the objects they initialize. Hence a string literal is
not always the same as the first string within it (because in C,
a "string" is simply a \0-terminated data structure; if the string
literal contains \0 characters, it produces multiple adjacent
strings).
 
A

Alan Balmer

On 2005-10-27 said:
Thank you ;-)

As long as everyone understands that they're not _really_ registers.
Now, in actual answer for his question, that depends on where you
declare this - the string data will be in automatic storage [aka
"stack"] in the first case if declared in a function, or in static
storage if you declared it at the top level of the file. In the
second case, these are string literals and will often be stored in
a nonwritable segment.

No, the actual answer to his question is "It depends. You should
ask in a newsgroup which knows the answer for whatever
implementation you are using." This could be followed by the
(on-topic) statement that "In most cases, you shouldn't care where
it's stored. You should only care that one form is modifiable, and
the other is not."

And no-one but me actually told him the part about one being
non-modifiable

Both Christopher and Neil did. More precisely, imo.
 
M

Michael Wojcik

and you forgot malloc - which is what "heap" generally means.

What makes you think Walter forgot malloc? It's not a storage
class, and C does not have "malloc variables".

Other people have - rightly, IMO - already questioned what
advantage your proposed "convenience" terms provide.
 
J

Jordan Abel

What makes you think Walter forgot malloc? It's not a storage
class, and C does not have "malloc variables".

It's a kind of memory. a place where things can exist. I guess I was
thinking "object" rather than variable

as in, char *foo=malloc(10);

the object (*foo) exists in malloc space.
Other people have - rightly, IMO - already questioned what
advantage your proposed "convenience" terms provide.

None at all. My point was that they're just terms, and there's no
reason to harp on someone using "the wrong terms" when it's
perfectly clear what they mean.
 
M

Mark McIntyre

None at all. My point was that they're just terms, and there's no
reason to harp on someone using "the wrong terms"

Indeed. So if someone insisted on calling your new car a Mazda when it
was a Maserati,or your wife a porker instead of a corker... thats ok,
they're just terms.

when it's perfectly clear what they mean.

But its manifestly not. Otherwise questions wouldn't get asked about
it...
 
T

Tim Rentsch

What makes you think Walter forgot malloc? It's not a storage
class, and C does not have "malloc variables".

It's true that C does not have "malloc variables". But it isn't
true that the only distinction in C is whether a variable is
static, auto, or register. There are also distinctions about
objects, which might or might not be associated with a particular
variable. 6.2.4 p1 identifies three storage durations: static,
automatic, and allocated. It happens that only the first two of
these kinds of objects are associated with particular variables,
but the Standard does explicitly distinguish the third kind.
 
E

Emmanuel Delahaye

Thomas Zhu a écrit :
But I do not know where are they in the memory.
would someone tell me ?

char s[][10]={"good", "morning"}; // at stack?

Nope. There are no strings. There are initialized arrays of char and
there are either in the static memory:

char s[][10]={"good", "morning"};
static char s[][10]={"good", "morning"};

....
{
static char s[][10]={"good", "morning"};
}

or in the automatic memory:

....
{
char s[][10]={"good", "morning"};
}
char *t[] = {"good", "morning"}; // at heap?

Nope.

The strings are somewhere in place that should be considered as
read-only. Details are irrelevent.
 
M

Michael Wojcik

It's true that C does not have "malloc variables". But it isn't
true that the only distinction in C is whether a variable is
static, auto, or register. There are also distinctions about
objects,

Object characteristics are not variable characteristics. Some
variable characteristics imply object characteristics; auto storage
class (a variable characteristic) implies automatic storage duration
(an object characteristic). However, Walter's statement is correct
as written (if "only distinction in C" is read as "only distinction
regarding storage among variables in C").
which might or might not be associated with a particular
variable.

Which is why "malloc" (ie allocated storage duration) is not a
characteristic of variables, and is orthogonal to the list Walter
provided.

An allocated-storage-duration object may be pointed to by a
variable of an appropriate pointer type of any of the three storage
classes.

I submit that nothing is gained by conflating storage class and
storage duration. That is the substance of my initial objection.
 
T

Tim Rentsch

Object characteristics are not variable characteristics. Some
variable characteristics imply object characteristics; auto storage
class (a variable characteristic) implies automatic storage duration
(an object characteristic). However, Walter's statement is correct
as written (if "only distinction in C" is read as "only distinction
regarding storage among variables in C").

Yes, but that isn't what he wrote. Jordan's response seems
perfectly reasonable as a response to what Walter actually
wrote. Of course it may be that Jordan selectively quoted
to make his response seem more reasonable, but I don't know
that because I didn't read the earlier postings.


[snip]
I submit that nothing is gained by conflating storage class and
storage duration. That is the substance of my initial objection.

It seems like you're objecting to something either that
wasn't said or was said in something outside of what I was
responding to. What I read was only the quoted part above,
and it doesn't say anything about conflating storage class
and storage duration. Maybe you see such a connection when
you read it, but it sure doesn't seem like it's in the
actual writing. Perhaps you were carrying forward some
context that came out of earlier postings in the thread, but
weren't quoted?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,170
Messages
2,570,925
Members
47,468
Latest member
Fannie44U3

Latest Threads

Top