473,287 Members | 1,927 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,287 software developers and data experts.

why char *p = "can not modiy"; char p[] = "can modify"

when define
char *p = " can not modify";

p[0] ='b' ;is not allowed,

but if you declare p as
char p[] = "can modify";

p[0] = 'b'; is ok?
why?
what's difference between the two declaration + definition?
Nov 14 '05 #1
13 2473
ba*********@gmail.com wrote:
when define
char *p = " can not modify";
This defines nothing more than a single pointer that is initialized
to point to a literal string, i.e. a string that resides in memory
that you're not allowed to modify.
p[0] ='b' ;is not allowed, but if you declare p as
char p[] = "can modify";


This definition is quite different. It gives you an array of chars,
(just large enough to hold as many characters as the string "can
modify" has, plus one extra for the trailing '\0' character) and
that is initialized to that string. So that second declaration is
basically an abbreviation for

char p[ sizeof "can modify" ];
strcpy( p, "can modify" );

while the first definition does not involve any implicit strcpy()
but just assigns an address in non-modifiable memory to the pointer.

Regards, Jens

--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #2
[newbie answer]
ba*********@gmail.com wrote:
when define
char *p = " can not modify";

p[0] ='b' ;is not allowed,
p contains the address of the string " can not modify".
This string can be anywhere -- even in ROM.

You can change 'p' itself, not its contents.
but if you declare p as
char p[] = "can modify";
'p' is created here, the same way as a int would;
Its contents are then /copied/ from the string "can modify" which
can be anywhere -- even on ROM.
p[0] = 'b'; is ok?
why?
You're changing a copy of the constant, and that copy is changeable.
what's difference between the two declaration + definition?

With the first 'p' you allocate space for a pointer.

With the second 'p' you allocate as much space as needed for all the
characters (including the terminating '\0') in the string.

HTH
--
USENET would be a better place if everybody read: | to mail me: simply |
http://www.catb.org/~esr/faqs/smart-questions.html | "reply" to this post, |
http://www.netmeister.org/news/learn2quote2.html | *NO* MIME, plain text |
http://www.expita.com/nomime.html | and *NO* attachments. |
Nov 14 '05 #3
With: char *p = "something", You declare pointer that points to string
"something", and many compilers will place string in const section, so
changing this data is not good. Some compilers just put string in data
section (I think all Borland compilers, but not for sure) and changin this
data is OK. But, this source will not be portable.

With: char p[] = "something", You declare array, not pointer to string.
Becuase p is array it is logical that You can change value of array.

P.S.
Even MinGW does not issue any warning about this, but code will not work.

Nov 14 '05 #4
On 8 Nov 2004 16:02:38 -0800, ba*********@gmail.com wrote:
when define
char *p = " can not modify";

p[0] ='b' ;is not allowed,

but if you declare p as
char p[] = "can modify";

p[0] = 'b'; is ok?
why?
what's difference between the two declaration + definition?


The first declares a pointer which points to a string literal. The
string literal has static duration and the language standard says that
any attempt to modify it invokes undefined behavior.

The second declares an array which is initialized with the specified
characters (including the terminating '\0'). Whether or not the
string literal actually exists in your program is an implementation
issue not relevant to this newsgroup. Since your array is not defined
const, it is legal to modify it.
<<Remove the del for email>>
Nov 14 '05 #5
[Picking a post at random]
char *p = " can not modify";

p[0] ='b' ;is not allowed,


[Various people say that it shouldn't/won't work]

I have very vague recollections that there was (is?)a
Unix library function (probably several) for generating
temporary filenames:

extern void mktemp(char *s);

The idea was that you gave it a base name, such as
"abcdef0000000" and it would replace all the terminal
digits with a sequential number, or something. Anyway,
all the examples of its use that I saw, passed it
a quoted (i.e. constant) string. Calling the function
then overwrote that string.

Did I remember this right ?
What would happen if a file fragment had two different
string variables pointing to different (but identical)
strings, like this:

#include <stdio.h>

static void f1(void)
{
char *aa = "Bugger";
fprintf(stdout,"aa=%d\n",(int)aa);
mktemp(aa);
}

static void f2(void)
{
char *bb = "Bugger";
fprintf(stdout,"bb=%d\n",(int)bb);
mktemp(bb);
}
extern void main(void)
{
f1();
f2();
}

I thought all identical string constants were replaced by
a single copy at compile time, so the two printfs above
would yield the same number.
Nov 14 '05 #6


Endymion Ponsonby-Withermoor III wrote:
[Picking a post at random]

char *p = " can not modify";

p[0] ='b' ;is not allowed,


[Various people say that it shouldn't/won't work]

I have very vague recollections that there was (is?)a
Unix library function (probably several) for generating
temporary filenames:

extern void mktemp(char *s);

The idea was that you gave it a base name, such as
"abcdef0000000" and it would replace all the terminal
digits with a sequential number, or something. Anyway,
all the examples of its use that I saw, passed it
a quoted (i.e. constant) string. Calling the function
then overwrote that string.

Did I remember this right ?


This, I do not know. I just use C99's tmpnam() and
tmpfile() functions (which gives you a valid file
name/path which clashes with nothing or opens a
temporary file which will be removed when closed).

What would happen if a file fragment had two different
string variables pointing to different (but identical)
strings, like this:

#include <stdio.h>

static void f1(void)
{
char *aa = "Bugger";
fprintf(stdout,"aa=%d\n",(int)aa);
mktemp(aa);
}

static void f2(void)
{
char *bb = "Bugger";
fprintf(stdout,"bb=%d\n",(int)bb);
mktemp(bb);
}
extern void main(void)
{
f1();
f2();
}

I thought all identical string constants were replaced by
a single copy at compile time, so the two printfs above
would yield the same number.


This is not determined by the standard. A good compiler
probably will do this. Apart from that, it is a Bad Idea
to use a mere (int) cast for pointer output.
And void is no longer a valid return type for main().
It seems you have been out of business for over fifteen
years.
<OT>
Just had a look at 'man 3 mktemp'; your above code
will not work and is dangerous. Maybe this helps you:
--------------------------------------------------------
mktemp - make a unique temporary file name

SYNOPSIS
#include <stdlib.h>

char *mktemp(char *template);

DESCRIPTION
The mktemp() function generates a unique temporary file name
from template. The last
six characters of template must be XXXXXX and these are replaced
with a string that
makes the filename unique. Since it will be modified, template
must not be a string constant, but should be declared as a
character array.

RETURN VALUE
The mktemp() function returns NULL on error (template did not
end in XXXXXX) and template otherwise. If the call was
successful, the last six bytes of template will have
been modified in such a way that the resulting name is unique
(does not exist already).
If the call was unsuccessful, template is made an empty string.

ERRORS
EINVAL The last six characters of template were not XXXXXX.

CONFORMING TO
BSD 4.3. POSIX dictates tmpnam(3).

NOTE
The prototype is in <unistd.h> for libc4, libc5, glibc1; glibc2
follows the Single Unix Specification and has the prototype in
<stdlib.h>.

BUGS
Never use mktemp(). Some implementations follow BSD 4.3 and
replace XXXXXX by the current process id and a single letter,
so that at most 26 different names can be returned.
Since on the one hand the names are easy to guess, and on the
other hand there is a race between testing whether the name
exists and opening the file, every use of mktemp() is a
security risk. The race is avoided by mkstemp(3).
--------------------------------------------------------
</OT>
Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #7

"Endymion Ponsonby-Withermoor III"
<m_a_r_v_i_n@para----and----.want-to-do.coe.ukk> wrote in message
news:cm**********@newsg1.svr.pol.co.uk...
I have very vague recollections that there was (is?)a
Unix library function (probably several) for generating
temporary filenames:

extern void mktemp(char *s);

The idea was that you gave it a base name, such as
"abcdef0000000" and it would replace all the terminal
digits with a sequential number, or something. Anyway,
all the examples of its use that I saw, passed it
a quoted (i.e. constant) string. Calling the function
then overwrote that string.

Did I remember this right ?
Yes.

<quote
http://www.manpage.org/cgi-bin/man/man2html/usr/share/man/man3/mktemp.3.gz>
The mktemp() function generates a unique temporary file name from template.
The last six characters of template must be XXXXXX and these are replaced
with a string that makes the filename unique. Since it will be modified,
template must not be a string constant, but should be declared as a
character array.
</quote>
What would happen if a file fragment had two different
string variables pointing to different (but identical)
strings, like this:
<snip code>
I thought all identical string constants were replaced by
a single copy at compile time, so the two printfs above
would yield the same number.


For many compilers that's true, but IIRC that's compiler-dependent. So do
not rely on it. It's (IIRC, again) not prescribed by The Standard. However,
i'd be the last to consider myself an
expert on The Standard (she said modestly).
Nov 14 '05 #8
In article <news:cm**********@newsg1.svr.pol.co.uk>
Endymion Ponsonby-Withermoor III
<m_a_r_v_i_n@para----and----.want-to-do.coe.ukk> wrote:
I have very vague recollections that there was (is?)a
Unix library function (probably several) for generating
temporary filenames:

extern void mktemp(char *s);

The idea was that you gave it a base name, such as
"abcdef0000000" and it would replace all the terminal
digits with a sequential number, or something. Anyway,
all the examples of its use that I saw, passed it
a quoted (i.e. constant) string. Calling the function
then overwrote that string.

Did I remember this right ?


There were indeed some old Unix programs that had code of the form:

char *p = mktemp("/tmp/progXXXXXX");

When we switched to ANSI C, they broke.

We fixed them:

static char buf[] = "/tmp/progXXXXXX";
char *p = mktemp(buf);

and now they work. (In general, when we fixed them we tried to
stop using mktemp() in the first place, as the entire concept of
mktemp() was flawed. But the above sufficed as a first pass, if
necessary.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #9
On 8 Nov 2004 16:02:38 -0800, in comp.lang.c , ba*********@gmail.com wrote:
when define
char *p = " can not modify";
p points to a string literal.
but if you declare p as
char p[] = "can modify";
p points to an array of char.
p[0] = 'b'; is ok?
why?
Because the C standard says so.
what's difference between the two declaration + definition?


one points to a string literal, the other to an array.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 14 '05 #10
Mark McIntyre wrote:

On 8 Nov 2004 16:02:38 -0800, in comp.lang.c , ba*********@gmail.com wrote:
when define
char *p = " can not modify";


p points to a string literal.
but if you declare p as
char p[] = "can modify";


p points to an array of char.


&p points to an array of char.

--
pete
Nov 14 '05 #11
On Wed, 10 Nov 2004 22:50:17 UTC, Mark McIntyre
<ma**********@spamcop.net> wrote:
On 8 Nov 2004 16:02:38 -0800, in comp.lang.c , ba*********@gmail.com wrote:
when define
char *p = " can not modify";
p points to a string literal.
but if you declare p as
char p[] = "can modify";


p points to an array of char.


No it points nowhere as p is not a pointer. p is an array of char in
the length of the given string including a null byte.
p[0] = 'b'; is ok?
why?


Because the C standard says so.


No, not really. p[0] is the first byte of an array of char, not a
string literal.
what's difference between the two declaration + definition?


one points to a string literal, the other to an array.

No, one is a string literal, the other is an array of char. There is
no pointer in sight.

A string literal is NOT a pointer - but can be handled as if it were
in assignents.
An array is NOT a pointer - but can be handled as if it were in
assignments.

Even as the compiler will decide to handle the name of an array
without subscription to handle as a pointer - it is NOT a pointer.

A pointer is not an array but can point to a member of one.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #12
pete wrote:

Mark McIntyre wrote:

On 8 Nov 2004 16:02:38 -0800, in comp.lang.c ,
ba*********@gmail.com wrote:
when define
char *p = " can not modify";


p points to a string literal.


p points to a string.

--
pete
Nov 14 '05 #13
On Mon, 08 Nov 2004 19:35:46 -0500, "hari4063"
<za**************@pmf.unsa.ba> wrote:
With: char *p = "something", You declare pointer that points to string
"something", and many compilers will place string in const section, so
changing this data is not good. Some compilers just put string in data
section (I think all Borland compilers, but not for sure) and changin this
data is OK. But, this source will not be portable.

With: char p[] = "something", You declare array, not pointer to string.
Becuase p is array it is logical that You can change value of array.

P.S.
Even MinGW does not issue any warning about this, but code will not work.


(assuming "this" is writing into a string literal value)

It (actually GCC, which is the compiler mingw includes) does warn if
you use -Wwrite-strings. More specifically it (nonstandardly) makes
the string literal value officially const and so warns about losing
const qualification on the pointer; if you fix that by qualifying the
pointer, it warns about any attempt to store through it, unless you
cast away the const somewhere or cheat (by punning, or strchr etc.)
- David.Thompson1 at worldnet.att.net
Nov 14 '05 #14

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

Similar topics

4
by: Askari | last post by:
Yesterday, ALL code in python work and nothing when I close(finish) a code. Today, when I close, some raise this windows error : Instruction at "0x00FC3D70" use memory address "0x00000000". Can't...
2
by: Robin Tucker | last post by:
I have some code that dynamically creates a database (name is @FullName) and then creates a table within that database. Is it possible to wrap these things into a transaction such that if any one...
3
by: Ian Lazarus | last post by:
// why is the error message being generated? // Microsoft Visual C/C++ 5.0 class Bar { public: void Log(const char* p){ } }; class Foo : public Bar
4
by: wangzhihuii | last post by:
Hi all, I'm really confused, can cout<<""; contribute anything to the routine ?!! my programm won't work properly without this trivial sentence. Sincerely vivian
11
by: Robert Lacoste | last post by:
Dear Access gurus, I was using since years Access 97, now under XP SP2, without any problem. However I've just reformatted my HD (viruses...), reinstalled XP SP2, and then I am no longer able to...
0
by: Kevin Mitchell | last post by:
I have an NT shared hosting account, but the provider names the script/write folder cgi-bin. I want to place DLLs in the cgi-bin directory and get them to work in my Web applications. What do I...
0
by: Thomas W | last post by:
Hello, I'm trying to call a function from a C++ dll which is declared as VARIANT DLLEXPORT ExecuteFunction (LPCSTR); This function (which I can't change) executes a SQL query and returns a...
15
by: jjh | last post by:
So with infile I have this so far: #define MAXBOOKS 9 ifstream infile("library.txt"); struct Book { title } while(true) {
6
by: Army1987 | last post by:
Reliable sources (whose names I'm not allowed to disclose) told me that on the next version of the Deathstation (version 10000, or DS10K) an integral type (they didn't tell which) will have a odd...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...

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.