By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,114 Members | 1,570 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,114 IT Pros & Developers. It's quick & easy.

Embedded Strings -- Arrays or pointers?

P: n/a


When you have compile-time strings like:

"The file is of unknown format."

What kind of variables do you use to store it? At the moment I'm using:

char const str[] = "The file is of unknown format.";

Do some of you use:

const char* const str = "The file is of unknown format.";

-Tomás
Feb 10 '06 #1
Share this Question
Share on Google+
31 Replies


P: n/a
* Tomás:
When you have compile-time strings like:

"The file is of unknown format."

What kind of variables do you use to store it? At the moment I'm using:

char const str[] = "The file is of unknown format.";

Do some of you use:

const char* const str = "The file is of unknown format.";


Perhaps some do, but I think it would be less than smart to discard
information for such raw data, and to write more to do that.

There is also the question of whether to write

std::string const str = "The file is of unknown format";

and at least for one learning the language I think it's a good idea to
use std::string exclusively, and not delve into the realm of pointers
and raw arrays, simply not get _used_ to the low-level features.

However, there are some scenarios where the std::string constant isn't
possible or advisable.

And of course the strings may instead be embedded in some resource data
structure in the program or in a dynamic library, for
internationalization, but that is platform-dependent and tool-dependent
and therefore outside the scope of discussion in this group.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 10 '06 #2

P: n/a

Tomás wrote:
When you have compile-time strings like:

"The file is of unknown format."

What kind of variables do you use to store it? At the moment I'm using:

char const str[] = "The file is of unknown format.";

Do some of you use:

const char* const str = "The file is of unknown format.";

-Tomás


As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";

now you have two zeroterminated memory areas and two pointers.

The diffrence is in literals, as below:
char* pstr2={'e','r','r','o','r'};//illegal
char astr2[]=pstr;;//illegal
char astr3[]={'e','r','r','o','r','\0'};//legal
char astr3[]={'e','r','r','o','r'};//legal, but not a string since no
zero is appended

Strings are represented by arrays, they are not arrays.
/Jesper

Feb 10 '06 #3

P: n/a

<je****@alphacash.se> wrote in message
news:11*********************@g47g2000cwa.googlegro ups.com...

Tomás wrote:
When you have compile-time strings like:

"The file is of unknown format."

What kind of variables do you use to store it? At the moment I'm using:

char const str[] = "The file is of unknown format.";

Do some of you use:

const char* const str = "The file is of unknown format.";

-Tomás


As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";
---
The above two are not same.
pstr[1] = 'a'; // Illegal
astr[1] = 'a'; // Legal

Sharad
Feb 10 '06 #4

P: n/a

Sharad Kala wrote:
---
The above two are not same.
pstr[1] = 'a'; // Illegal
astr[1] = 'a'; // Legal

Sharad

No thats false.
pstr[1] = 'a'; is legal, its not safe, but it is legal.
standard behaviour is
pstr[1] = 'a';
compiles to
*(pstr+(sizeof(*pstr)))='a';

/Jesper

Feb 10 '06 #5

P: n/a
* je****@alphacash.se:
Sharad Kala wrote:
---
The above two are not same.
pstr[1] = 'a'; // Illegal
astr[1] = 'a'; // Legal

Sharad

No thats false.
pstr[1] = 'a'; is legal, its not safe, but it is legal.
standard behaviour is
pstr[1] = 'a';
compiles to
*(pstr+(sizeof(*pstr)))='a';


In the context (which you snipped) the assignment is not valid, because
the pointer points to a literal string constant.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 10 '06 #6

P: n/a
* je****@alphacash.se:
pstr[1] = 'a';
compiles to
*(pstr+(sizeof(*pstr)))='a';


Not in general (and it is the general you're trying to illustrate?).

It "compiles to", in the sense of being equivalent with,

*(pstr+1) = 'a';

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 10 '06 #7

P: n/a
je****@alphacash.se wrote:

As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";


At this moment, yes, you are ignorant as hell.
pstr resides in read-only memory and trying to modify it
is UB, whereas modifying astr is ok.

HTH,
- J.
Feb 10 '06 #8

P: n/a

Alf P. Steinbach wrote:
* je****@alphacash.se:
pstr[1] = 'a';
compiles to
*(pstr+(sizeof(*pstr)))='a';


Not in general (and it is the general you're trying to illustrate?).

It "compiles to", in the sense of being equivalent with,

*(pstr+1) = 'a';

yes its the general I'm after. And you are misstaken,
because operator+(char*,int) defines the size of the element.
The code below works fine. (borland, ansicompliant,force c++)

class CClass
{
int i[2];
public:
CClass& operator=(int in){i[0]=in;i[1]=in;}
};

int u[]={1,2,3};
CClass c[3];

template <class T>
void MyPoint(T* arg)
{
arg[1]=3;
}
int main() {
MyPoint(u);
MyPoint(c);
}

Feb 10 '06 #9

P: n/a
I will give on the point concerning the const declarations that
I sadly snipped away. Sorry about that. My only excuse is that you used

the variable names astr and pstr which i introduced and did not declare
const.
Sorry.
But I will remain adamant that the Rvalues are the same type. :-)

BTW. this is the first time I have ever seen the syntax:
const char * const str="string";

Does that second const induce the area protection?
And if so, how would I protect an array the same way?

Feb 10 '06 #10

P: n/a
Darn. Should have tested before I gave in :-)
With these declarations:

char const astr[] ="array hello";
const char* const pstr="pointer hello";
both:
pstr[1]='o';
astr[1]='o';
are illegal. (again borland, ansi,force c++)

Feb 10 '06 #11

P: n/a
* je****@alphacash.se:
Alf P. Steinbach wrote:
* je****@alphacash.se:
pstr[1] = 'a';
compiles to
*(pstr+(sizeof(*pstr)))='a'; Not in general (and it is the general you're trying to illustrate?).

It "compiles to", in the sense of being equivalent with,

*(pstr+1) = 'a';

yes its the general I'm after. And you are misstaken,


I'm sorry, that's incorrect.

because operator+(char*,int) defines the size of the element.
And I'm sorry, but that's meaningless.

The code below works fine. (borland, ansicompliant,force c++)


And triple sorry, that code has nothing whatsoever to do with anything.

[code snipped]
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 10 '06 #12

P: n/a

Jacek Dziedzic wrote:
je****@alphacash.se wrote:

As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";


At this moment, yes, you are ignorant as hell.
pstr resides in read-only memory and trying to modify it
is UB, whereas modifying astr is ok.

HTH,
- J.

This is just plain wrong, any compiler can tell you so.
There is no such thing as read-only memory. (unless you think it will
be stored on a cdrom, or an actual rom which is a paradox)
no the memory is protected. Operating system protects memory areas.
Compiler
stops you from making certain mistakes. And as both above arrays are
declared non const you can modify them to your hearts content.

Feb 10 '06 #13

P: n/a

Alf P. Steinbach wrote:
* je****@alphacash.se:
Alf P. Steinbach wrote:
* je****@alphacash.se:
pstr[1] = 'a';
compiles to
*(pstr+(sizeof(*pstr)))='a';
Not in general (and it is the general you're trying to illustrate?).

It "compiles to", in the sense of being equivalent with,

*(pstr+1) = 'a';
yes its the general I'm after. And you are misstaken,


I'm sorry, that's incorrect.

Put it to the test. In this case empirical evidence is not so far away.
because operator+(char*,int) defines the size of the element.


And I'm sorry, but that's meaningless.

The code below works fine. (borland, ansicompliant,force c++)


And triple sorry, that code has nothing whatsoever to do with anything.


I do confess slight frustration now.
You state:
pstr[1] = 'a'; compiles to *(pstr+1) = 'a';
I give you that because sizeof(char) IS 1 and we are accessing element#
1.
I prove to you using code and arrays with diffrent size elements that
what compiler does is:
pstr[1] = 'a'; compiles to *(pstr+(1*sizeof(*pstr))) = 'a';

since it arrives at the correct memory adress regardless of the size of
the elements, size is entered in the computation. This you try to pass
off as irrelevant...
Did you understand the snippet? (no offence intended, I just want to
know if you need me to explain something about it)

Feb 10 '06 #14

P: n/a
je****@alphacash.se wrote:
Alf P. Steinbach wrote:
* je****@alphacash.se:
Alf P. Steinbach wrote:
* je****@alphacash.se:
> pstr[1] = 'a';
> compiles to
> *(pstr+(sizeof(*pstr)))='a';
Not in general (and it is the general you're trying to illustrate?).

It "compiles to", in the sense of being equivalent with,

*(pstr+1) = 'a';

yes its the general I'm after. And you are misstaken, I'm sorry, that's incorrect.

Put it to the test. In this case empirical evidence is not so far away.


Undefined behaviour can, unfortunately, mean you see what you expect.
because operator+(char*,int) defines the size of the element.

And I'm sorry, but that's meaningless.

The code below works fine. (borland, ansicompliant,force c++)

And triple sorry, that code has nothing whatsoever to do with anything.


I do confess slight frustration now.
You state:
pstr[1] = 'a'; compiles to *(pstr+1) = 'a';
I give you that because sizeof(char) IS 1 and we are accessing element#
1.


When you add 1 to a pointer, it offsets by the length of the pointee.
Not 1.
I prove to you using code and arrays with diffrent size elements that
what compiler does is:
pstr[1] = 'a'; compiles to *(pstr+(1*sizeof(*pstr))) = 'a';

#include <iostream>

int main() {
unsigned char chararr[2];
unsigned long longarr[2];
std::cout << (unsigned long)&chararr[1] -
(unsigned long)&chararr[0]
<< "\n";
std::cout << (unsigned long)&longarr[1] -
(unsigned long)&longarr[0]
<< "\n";
}
since it arrives at the correct memory adress regardless of the size of
the elements, size is entered in the computation. This you try to pass
off as irrelevant...
I don't see your code. See above.
Did you understand the snippet? (no offence intended, I just want to
know if you need me to explain something about it)


Does the code above show the issue?

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 10 '06 #15

P: n/a
* je****@alphacash.se:
I prove to you using code and arrays with diffrent size elements that
what compiler does is:
pstr[1] = 'a'; compiles to *(pstr+(1*sizeof(*pstr))) = 'a';
No, you haven't proved any such thing.

since it arrives at the correct memory adress regardless of the size of
the elements, size is entered in the computation.
Yes, but not at the C++ level.

This you try to pass
off as irrelevant...
Did you understand the snippet? (no offence intended, I just want to
know if you need me to explain something about it)


It was all understood, and irrelevant. Try out *(p+n), for p of type
T*. For built-in indexing operation it is by definition the same as
p[n], and therefore, also, n[p]...

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 10 '06 #16

P: n/a

<je****@alphacash.se> wrote in message
|
| Jacek Dziedzic wrote:
| > je****@alphacash.se wrote:
| > >
| > > As far as I know there is no diffrence between them.
| > > I might be ignorant as hell. Is exactly the same.
| > > char astr[]="array hello";
| > > char* pstr="pointer hello";
| >
| > At this moment, yes, you are ignorant as hell.
| > pstr resides in read-only memory and trying to modify it
| > is UB, whereas modifying astr is ok.
| >
| > HTH,
| > - J.
| This is just plain wrong, any compiler can tell you so.
| There is no such thing as read-only memory. (unless you think it will
| be stored on a cdrom, or an actual rom which is a paradox)
| no the memory is protected. Operating system protects memory areas.
| Compiler
| stops you from making certain mistakes. And as both above arrays are
| declared non const you can modify them to your hearts content.

I agree that Standard doesn't promise that contents of pstr lie in a read
only region (even though most Unix compilers treat it so). But Standrad
enforces that trying to modify this memory leads to undefined behavior.
Undefined behavior means that it may work, or lead to core dump, or erase
your hard disk etc etc.

Sharad

P.S. - Try to read what others are saying more carefully.

Feb 10 '06 #17

P: n/a

<je****@alphacash.se> wrote in message
|
| Alf P. Steinbach wrote:
| > * je****@alphacash.se:
| > > Alf P. Steinbach wrote:
| > >> * je****@alphacash.se:
| > >>> pstr[1] = 'a';
| > >>> compiles to
| > >>> *(pstr+(sizeof(*pstr)))='a';
| > >> Not in general (and it is the general you're trying to illustrate?).
| > >>
| > >> It "compiles to", in the sense of being equivalent with,
| > >>
| > >> *(pstr+1) = 'a';
| > >>
| > > yes its the general I'm after. And you are misstaken,
| >
| > I'm sorry, that's incorrect.
| Put it to the test. In this case empirical evidence is not so far away.
| >
| >
| > > because operator+(char*,int) defines the size of the element.
| >
| > And I'm sorry, but that's meaningless.
| >
| >
| > > The code below works fine. (borland, ansicompliant,force c++)
| >
| > And triple sorry, that code has nothing whatsoever to do with anything.
|
| I do confess slight frustration now.
| You state:
| pstr[1] = 'a'; compiles to *(pstr+1) = 'a';
| I give you that because sizeof(char) IS 1 and we are accessing element#
| 1.
| I prove to you using code and arrays with diffrent size elements that
| what compiler does is:
| pstr[1] = 'a'; compiles to *(pstr+(1*sizeof(*pstr))) = 'a';

That's irrelevant as far as the language is concerned. Given any array,
a[b] is evaluated as *(a + b). Compilers are smart enough to access the
right memory location using pointer arithmetic.

Sharad

Feb 10 '06 #18

P: n/a

je****@alphacash.se wrote:

[]
As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";
They are different.

Using char[] for string literals provides more information at compile
time. Consider the effects of:

unsigned a = sizeof(astr), b = sizeof(pstr);

Now a is the size of the literal including zero terminator, while b is
merely the size of the pointer.
From a dynamic linker perspective, char[] may be better than char* for

string literals. More information on that
http://people.redhat.com/drepper/dsohowto.pdf

Feb 10 '06 #19

P: n/a

Alf P. Steinbach wrote:
* je****@alphacash.se:
I prove to you using code and arrays with diffrent size elements that
what compiler does is:
pstr[1] = 'a'; compiles to *(pstr+(1*sizeof(*pstr))) = 'a';


No, you haven't proved any such thing.

since it arrives at the correct memory adress regardless of the size of
the elements, size is entered in the computation.


Yes, but not at the C++ level

I am beginning to think I'am off topic due to ignorance on
what is concidered c and what is considered c++.
What separates them form each other? Is there such a thing as pure c++?

I was thinking about the sum of the both and what can be done and not.
You seem to know:
how do
int i[]={1,2,3,4};
void main()
{
i[2]=6;
}
compile and on what level is stuff happenning?

Feb 10 '06 #20

P: n/a

<je****@alphacash.se> wrote in message |
| Alf P. Steinbach wrote:
| > * je****@alphacash.se:
| > > I prove to you using code and arrays with diffrent size elements that

[snip]

| I am beginning to think I'am off topic due to ignorance on

You are not offtopic, but incorrect in your understanding.

| what is concidered c and what is considered c++.
| What separates them form each other? Is there such a thing as pure c++?

That makes little sense to me. C and C++ are two different programming
languages. C++ has tried to maintain compatibility with C, but not every
valid C program is a valid C++ program.

| I was thinking about the sum of the both and what can be done and not.
| You seem to know:
| how do
| int i[]={1,2,3,4};
| void main()

This exhibits undefined behavior. Main has _never ever_ in the history of
C++ returned void.

| {
| i[2]=6;

*(i + 2) = 6

Pointer aritmetic gets you to the right offset (i.e. i + 2*sizeof int).

| }
| compile and on what level is stuff happenning?

Sharad
Feb 10 '06 #21

P: n/a

Maxim Yegorushkin wrote:
je****@alphacash.se wrote:

[]
As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";


They are different.

Using char[] for string literals provides more information at compile
time. Consider the effects of:

unsigned a = sizeof(astr), b = sizeof(pstr);

Now a is the size of the literal including zero terminator, while b is
merely the size of the pointer.
From a dynamic linker perspective, char[] may be better than char* for

string literals. More information on that
http://people.redhat.com/drepper/dsohowto.pdf


Ok. This I can understand.
I did not consider array size being availble at compiletime.
I must confess I seldom use static arrays in any case. And have
probably come to
consider the pointer to be the same as the array.
Thank you.
/Jesper

Feb 10 '06 #22

P: n/a
In article <qY******************@news.indigo.ie>,
"Tomás" <NU**@NULL.NULL> wrote:
When you have compile-time strings like:

"The file is of unknown format."

What kind of variables do you use to store it? At the moment I'm using:

char const str[] = "The file is of unknown format.";

Do some of you use:

const char* const str = "The file is of unknown format.";


In *real* programs, I use whatever OS tools are available to store the
string outside the program and import it. In other words, there is a
file somewhere with a list of all my string literals, and I import them
into the program, the string literals are not imbedded in the code
itself.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Feb 10 '06 #23

P: n/a

Sharad Kala wrote:
This exhibits undefined behavior. Main has _never ever_ in the history of
C++ returned void.

*Blush* Well well... I think I'll just shut up :-)

Feb 10 '06 #24

P: n/a

Daniel T. wrote:

[]
In *real* programs, I use whatever OS tools are available to store the
string outside the program and import it. In other words, there is a
file somewhere with a list of all my string literals, and I import them
into the program, the string literals are not imbedded in the code
itself.


This is typical for gui applications with the rationale being i18n. Not
typical for servers.

Feb 10 '06 #25

P: n/a
je****@alphacash.se wrote:
Jacek Dziedzic wrote:
je****@alphacash.se wrote:

As far as I know there is no diffrence between them.
I might be ignorant as hell. Is exactly the same.
char astr[]="array hello";
char* pstr="pointer hello";


At this moment, yes, you are ignorant as hell.
pstr resides in read-only memory and trying to modify it
is UB, whereas modifying astr is ok.

HTH,
- J.

This is just plain wrong, any compiler can tell you so.
There is no such thing as read-only memory.


Strange. I have an EPROM which definitely thinks it's read-only as
long as you don't irradiate it. And there are many compilers who are
happy to agree with that observation. Certainly you don't expect that
the compiler arranges for an UV source if you write pstr[0]=0; ?

HTH,
Michiel Salters

Feb 10 '06 #26

P: n/a
Daniel T. wrote:
In article <qY******************@news.indigo.ie>,
"Tomás" <NU**@NULL.NULL> wrote:
Do some of you use:

const char* const str = "The file is of unknown format.";


In *real* programs, I use whatever OS tools are available to store the
string outside the program and import it. In other words, there is a
file somewhere with a list of all my string literals, and I import them
into the program, the string literals are not imbedded in the code
itself.


You know there are tools (like GNU's xgettext) which can find string
literals
even if they're embedded in the code itself? Keeping a separate file is
a
maintenance nightmare. Automatically creating it as part of your
automated
build is robust and easy.

HTH,
Michiel Salters

Feb 10 '06 #27

P: n/a
Sharad Kala wrote:

<je****@alphacash.se> wrote in message

I prove to you using code and arrays with diffrent size elements
that what compiler does is:
pstr[1] = 'a'; compiles to *(pstr+(1*sizeof(*pstr))) = 'a';


That's irrelevant as far as the language is concerned. Given any
array, a[b] is evaluated as *(a + b). Compilers are smart enough to
access the right memory location using pointer arithmetic.

Yes, that's why the seemingly odd construct:

char* arr[10];

0[arr] = 'a';

Is perfectly legal and meaningful.

Brian
Feb 10 '06 #28

P: n/a

Default User wrote:

[]
Yes, that's why the seemingly odd construct:

char* arr[10];
0[arr] = 'a';

Is perfectly legal and meaningful.


It is not. Had you declared arr as char arr[10], rather than char* ...,
it would have been.

Feb 13 '06 #29

P: n/a

Mi*************@tomtom.com wrote:
Strange. I have an EPROM which definitely thinks it's read-only as
long as you don't irradiate it. And there are many compilers who are
happy to agree with that observation. Certainly you don't expect that
the compiler arranges for an UV source if you write pstr[0]=0; ?


I was being stupid. I am beginning to get a clue as to what kind of
subjects we are dealing with in this group. I was only thinking about
PC:s but I know understand what is being ment by this relating to the
language only, and why the term "undefined behaviour" is being thrown
about to the extent it is. I appologize for my somewhat agressive
statements. I need to find a PC-programming forum instead. :-)

Feb 13 '06 #30

P: n/a
Hi Jesper

This has nothing to do with your platform. On a modern pc, the
operating system will protect the memory so that you e.g. can't
overwrite the operating system or the executable code. There is nothing
to prevent the compiler to putting fixed strings in to memory in which
your program is not allowed to write. In such a case, the modification
of a constant is assured to give you "unexpected" behaviour such a
signal being sent.

/Peter

Feb 13 '06 #31

P: n/a
Maxim Yegorushkin wrote:

Default User wrote:

[]
Yes, that's why the seemingly odd construct:

char* arr[10];
0[arr] = 'a';

Is perfectly legal and meaningful.


It is not. Had you declared arr as char arr[10], rather than char*
..., it would have been.


That was a typo, of course. Thanks for pointing it out, correctness is
always to be preferred.

Brian

Feb 13 '06 #32

This discussion thread is closed

Replies have been disabled for this discussion.