468,268 Members | 1,747 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,268 developers. It's quick & easy.

C novice question...

#include <stdio.h>

int main()
{
int i;
char *p="sarang";
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
char *k=p;
k[1]='u';
printf("%s",p);
}

i compiled it with gcc, and it shows error message,

i think the last 3 lines are problem.. Can anyone help me ?
Nov 13 '05 #1
17 1775
Next time, try to include the error message so we can use it to
determine the problem.

herrcho wrote:
#include <stdio.h>

int main()
{
int i;
char *p="sarang"; char *k;
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
/*char *k=p;*/ k=p;
k[1]='u';
printf("%s",p);
}

i compiled it with gcc, and it shows error message,

i think the last 3 lines are problem.. Can anyone help me ?


This will compile with warnings, but won't run properly because of the
k[1]='u' line.
To solve this change
char *p="sarang";
in
char p[]="sarang";

The p[] version causes memory for "sarang" to be allocated on the stack.
Your version hard codes "sarang" in the .rodata section of your program,
which is not writable.

Figure the last warning gcc gives you out yourself, it is informative
enough.

Mark

Nov 13 '05 #2
herrcho <he*********@kornet.net> wrote:
#include <stdio.h> int main()
{
int i;
char *p="sarang";
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
char *k=p;
k[1]='u';
printf("%s",p);
}
You promised that the program would return an int, but you
don't keep it... Better add a return statement.
i compiled it with gcc, and it shows error message, i think the last 3 lines are problem.. Can anyone help me ?


Due to the line

char *p="sarang";

p is pointing to what's called a literal string, i.e. a string that
resides somewhere in memory which you aren't allowed to modify (it
actually may get placed in ROM or the compiler could use the same
memory if e.g. you would write

char *p1="sarang";
char *p2="arang";

with p2 being just p1 + 1). Now you make k point to the same
memory location and then try to change what's stored there. And
that's the problem because you're not allowed to do this.

The simplest way around this problem is to make p a real array,
not just a pointer:

char p[ ] = "sarang";

p is now an array with memory that belongs to your program and
initialized to "sarang". Since you own the memory you also can
change it without any problems. p (without any additions) can
still be treated like a pointer to the first element of the array
in most cases, so the rest of the program will still work without
modifications.
Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Je***********@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring
Nov 13 '05 #3
On Mon, 15 Sep 2003 21:07:22 +0900 (KST), "herrcho" <he*********@kornet.net>
wrote:
#include <stdio.h>

int main()
{
int i;
char *p="sarang";
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
char *k=p;
Unless you are running a C99 compiler, the above statement is illegal.
Declarations cannot be mixed with statements; they must preceed the statements
in a block.

Move the declaration of k (char *k=p;) to the line immediately following the
declaration of p (char *p="sarang";)
k[1]='u';
printf("%s",p);
}

i compiled it with gcc, and it shows error message,

i think the last 3 lines are problem.. Can anyone help me ?


--
Lew Pitcher
IT Consultant, Enterprise Technology Solutions
Toronto Dominion Bank Financial Group

(Opinions expressed are my own, not my employers')
Nov 13 '05 #4

"herrcho" <he*********@kornet.net> schrieb im Newsbeitrag
news:bk**********@news1.kornet.net...
#include <stdio.h>

int main()
{
int i;
char *p="sarang"; p now points to the first character in a string literal, which is by
definition read only
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
char *k=p; the definition of k must be before any executable statement, unless you have
a C99 compiler.
k now points to the same read - only string k[1]='u'; you try to write to this string -- bang. printf("%s",p); you defined correctly main() returning an int, so better return one:
return 0;
or, if you #include stdlib.h, you can write the more descriptive
return EXIT_SUCCESS; }
btw, if you want to be sure that the result of your printf() statements
shows up immidiately, either append a '\n' to the format string or put a
fflush(stdout) after the printf() i compiled it with gcc, and it shows error message, segfault?
next time please be a little bit more precise:
was it a compiler diagnostic or did the program crash?
and what _was_ the exact error message?
i think the last 3 lines are problem.. Can anyone help me ?


Here is a corrected version of your code:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int i;
char p[] = "sarang";
char *k;

for(i = 0; i < 4; i++)
printf("%c", *(p+i));
printf("\n");

for(i = 0; i < 4; i++)
printf("%c", p[i]);
printf("\n");
printf(p);
printf("\n");

k = p;
k[1] = 'u';
printf("%s", p);
fflush(stdout);
return EXIT_SUCCESS;
}

HTH
Robert
Nov 13 '05 #5
Lew Pitcher wrote:
printf(p);
char *k=p;


Unless you are running a C99 compiler, the above statement is illegal.


How about in C99?
Can you declare a variable just anywhere, like that ?
Nov 13 '05 #6
herrcho wrote:
#include <stdio.h>

int main()
{
int i;
char *p="sarang";
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
char *k=p;
Potential problems here.
k[1]='u';
printf("%s",p);
}

i compiled it with gcc, and it shows error message,

i think the last 3 lines are problem.. Can anyone help me ?


What are the error messages? C99 will compile.
If you are using a C89 compiler then you will get an
error because the declaration of k is misplaced. ISO C89
does not allow mixed declarations.You will need to be
move the declaration up to the other declarations.

You have an additional problem that may cause the program to
crash. k will point to possibly read only memory. You
cannot safely assign to k[1].
Read faq question 1.32 located at:
http://www.eskimo.com/~scs/C-faq/q1.32.html
and change
char *p="sarang";
to
char p[] = "sarang";

/***************************/
#include <stdio.h>

int main(void)
{
int i;
char p[]="sarang";
char *k;

for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf("\n");
printf(p);
putchar('\n');
k=p;
k[1]='u';
printf("%s\n",p);
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa*@abowers.combase.com (remove the x)
http://www.geocities.com/abowers822/

Nov 13 '05 #7

"Capstar" <sp***@eg.homeip.net> schrieb im Newsbeitrag
news:3F**************@eg.homeip.net...
Next time, try to include the error message so we can use it to
determine the problem.

herrcho wrote:
#include <stdio.h>

int main()
{
int i;
char *p="sarang";

char *k;
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
/*char *k=p;*/

k=p;
k[1]='u';
printf("%s",p);
}

i compiled it with gcc, and it shows error message,

i think the last 3 lines are problem.. Can anyone help me ?


This will compile with warnings, but won't run properly because of the
k[1]='u' line.
To solve this change
char *p="sarang";
in
char p[]="sarang";

The p[] version causes memory for "sarang" to be allocated on the stack.
Your version hard codes "sarang" in the .rodata section of your program,
which is not writable.


Let me rephrase that :)
The p[] version causes the compiler to reserve writeable memory in the
length of "sarang" + 1character for the trailing '\0' wherever it wants and
initializes it with the characters 's' 'a' 'r' 'a' 'n' 'g' '\0',
while the char *p version causes the compiler to put the unnamed string
"sarang", again wherever it wants, and assign the address of the first
character to p. The space where the literal lays may or may not be writeable
memory, that does not matter, you are simply _not allowed_ to write to it.
It may, if you are unlucky, work on your platform, but crash on another one.
Simply undefined behavior, everything may happen...

Robert
Nov 13 '05 #8
In article <3F***********@mindspring.com>, pete wrote:
[cut]
How about in C99?
Can you declare a variable just anywhere, like that ?


Yes.

--
Andreas Kähäri
Nov 13 '05 #9
Robert Stankowic wrote:
"Capstar" <sp***@eg.homeip.net> schrieb im Newsbeitrag
news:3F**************@eg.homeip.net...

The p[] version causes memory for "sarang" to be allocated on the stack.
Your version hard codes "sarang" in the .rodata section of your program,
which is not writable.

Let me rephrase that :)
The p[] version causes the compiler to reserve writeable memory in the
length of "sarang" + 1character for the trailing '\0' wherever it wants and
initializes it with the characters 's' 'a' 'r' 'a' 'n' 'g' '\0',
while the char *p version causes the compiler to put the unnamed string
"sarang", again wherever it wants, and assign the address of the first
character to p. The space where the literal lays may or may not be writeable
memory, that does not matter, you are simply _not allowed_ to write to it.
It may, if you are unlucky, work on your platform, but crash on another one.
Simply undefined behavior, everything may happen...

Robert


Thanks, I'm not very well in explaining things. But it never hurts to
try. :)

Nov 13 '05 #10


Robert Stankowic wrote:
"herrcho" <he*********@kornet.net> schrieb im Newsbeitrag
news:bk**********@news1.kornet.net...
#include <stdio.h>

int main()
{
int i;
char *p="sarang";


p now points to the first character in a string literal, which is by
definition read only


Definition by what source?

If you read the faq question 1.32,
http://www.eskimo.com/~scs/C-faq/q1.32.html,
you will see that it says "possibly read only".

If you consult the Standards, you will see that the behavior is
undefined when you attempt to modify the array contents.

Of course the safe rule to follow, is to never attempt to modify the
array.

--
Al Bowers
Tampa, Fl USA
mailto: xa*@abowers.combase.com (remove the x)
http://www.geocities.com/abowers822/

Nov 13 '05 #11
Andreas Kahari wrote:

In article <3F***********@mindspring.com>, pete wrote:
[cut]
How about in C99?
Can you declare a variable just anywhere, like that ?


Yes.


Thank you.
Nov 13 '05 #12
herrcho wrote:
#include <stdio.h>

int main()
{
int i;
char *p="sarang";
Change this to
char p[] = "sarang";
Your form makes p a pointer to a string literal.
My form makes it an array populated with a string.
for(i=0;i<4;i++)
printf("%c",*(p+i));
printf("\n");
for(i=0;i<4;i++)
printf("%c",p[i]);
printf(p);
char *k=p;
k[1]='u';
printf("%s",p);
Make this
printf("%s\n",p);
Without a '\n' ending the last line of output, you are at the
mercy of the implementation and OS for what happens to that line.
It might never get written; it might be overwritten by the OS prompt;
it might have the OS prompt appended to its end; it might ...
}

i compiled it with gcc, and it shows error message,

i think the last 3 lines are problem.. Can anyone help me ?

--
Martin Ambuhl

Nov 13 '05 #13
Al Bowers wrote:

Robert Stankowic wrote:
"herrcho" <he*********@kornet.net> schrieb im Newsbeitrag
news:bk**********@news1.kornet.net...
#include <stdio.h>

int main()
{
int i;
char *p="sarang";


p now points to the first character in a string literal, which is by
definition read only


Definition by what source?

If you read the faq question 1.32,
http://www.eskimo.com/~scs/C-faq/q1.32.html,
you will see that it says "possibly read only".

If you consult the Standards, you will see that the behavior is
undefined when you attempt to modify the array contents.


The nondistinction of identical string literals,
rather than read only memory, is the reason for undefined behavior,
which the standards emphasize, by juxtaposition.

C89 Last Draft
3.1.4 String literals
Semantics
"Identical string literals of either form need not be distinct.
If the program attempts to modify a string literal of either form,
the behavior is undefined."

N869
6.4.5 String literals
[#6] It is unspecified whether these arrays are distinct
provided their elements have the appropriate values. If the
program attempts to modify such an array, the behavior is
undefined.

J.5 Common extensions
J.5.5 Writable string literals
[#1] String literals are modifiable (in which case,
identical string literals should denote distinct objects).
Nov 13 '05 #14

"Al Bowers" <xa*@abowers.combase.com> schrieb im Newsbeitrag
news:bk************@ID-169908.news.uni-berlin.de...


Robert Stankowic wrote:
"herrcho" <he*********@kornet.net> schrieb im Newsbeitrag
news:bk**********@news1.kornet.net...
#include <stdio.h>

int main()
{
int i;
char *p="sarang";


p now points to the first character in a string literal, which is by
definition read only


Definition by what source?

If you read the faq question 1.32,
http://www.eskimo.com/~scs/C-faq/q1.32.html,
you will see that it says "possibly read only".

If you consult the Standards, you will see that the behavior is
undefined when you attempt to modify the array contents.

Of course the safe rule to follow, is to never attempt to modify the
array.


OK, bad wording on my side. With "by definition" I actually meant one cannot
write to it without causing UB, which I'd better mentioned explicitely.
Thank you for the correction.

Robert
Nov 13 '05 #15


pete wrote:
Al Bowers wrote:
char *p="sarang";

p now points to the first character in a string literal, which is by
definition read only
If you consult the Standards, you will see that the behavior is
undefined when you attempt to modify the array contents.

The nondistinction of identical string literals,
rather than read only memory, is the reason for undefined behavior,
which the standards emphasize, by juxtaposition.


"by Definition read only"?
Why would you take such a position? This declaration has
nothing to do with identical string literals. The standard clearly
states in 6.7.8.32 on initialization

" On the other hand, the declaration
char *p = "abc";
defines p with type ‘‘pointer to char’’ and initializes it to
point to an object with type ‘‘array of char’’ with length 4
whose elements are initialized with a character string literal.
If an attempt is made to use p to modify the contents of the
array, the behavior is undefined. "
^^^^^^^^^^^^^^^^^^
C89 Last Draft 3.1.4 String literals
Semantics
"Identical string literals of either form need not be distinct.
If the program attempts to modify a string literal of either form,
the behavior is undefined."

N869
6.4.5 String literals
[#6] It is unspecified whether these arrays are distinct
provided their elements have the appropriate values. If the
program attempts to modify such an array, the behavior is
undefined.

J.5 Common extensions
J.5.5 Writable string literals
[#1] String literals are modifiable (in which case,
identical string literals should denote distinct objects).


This is another issue which assures that it there is a common
extension of writable string literals then the implementation is
required to treat idential string literals as distinct objects.

If the implemention allows writable string literals then:
char *p1 = "Hello World";
char *p2 = "Hello World";

p1 and p2 points to seperate objects such that if you modify one
you will not modify the other.

If the implementation does not allow modification of string literals
then in the above declarations, p1 and p2 may point to the same object.

The point is there is no definition that requires read only string
literals. The implementation is free to make them read only or allow
modifications. Of course, from the point of view of writing portable
code, one should aways treat string literals as read only.

--
Al Bowers
Tampa, Fl USA
mailto: xa*@abowers.combase.com (remove the x)
http://www.geocities.com/abowers822/

Nov 13 '05 #16

"Capstar" <sp***@eg.homeip.net> wrote in message
news:3F**************@eg.homeip.net...
Thanks, I'm not very well in explaining things. But it never hurts to
try. :)


From one perspective you were probably quite correct (I don't know though),
but from the comp.lang.c perspective there is nothing called .rodata and I
can
envision several architectures where such a section will not exist in the
compiled
code. What clc tries to do is to only give answers from the viewpoint of the
standard. Your explanation is a good example for why the standard disallows
writing to string literals, but you should specify that this sort of
explanation is
only valid for certain implementations. Just to clarify why Mr. S felt the
need
to rephrase you :)

--
Thomas.
Nov 13 '05 #17
Thomas Stegen wrote:
"Capstar" <sp***@eg.homeip.net> wrote in message
news:3F**************@eg.homeip.net...

Thanks, I'm not very well in explaining things. But it never hurts to
try. :)

From one perspective you were probably quite correct (I don't know though),
but from the comp.lang.c perspective there is nothing called .rodata and I
can
envision several architectures where such a section will not exist in the
compiled
code. What clc tries to do is to only give answers from the viewpoint of the
standard. Your explanation is a good example for why the standard disallows
writing to string literals, but you should specify that this sort of
explanation is
only valid for certain implementations. Just to clarify why Mr. S felt the
need
to rephrase you :)


I'll keep that in mind next time. ;)

Mark

Nov 13 '05 #18

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Christopher Richards | last post: by
2 posts views Thread by George | last post: by
21 posts views Thread by AES/newspost | last post: by
3 posts views Thread by herrcho | last post: by
1 post views Thread by Christo | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.