LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-20-2007, 11:54 AM   #1
koodoo
Member
 
Registered: Aug 2004
Location: a small village faraway in the mountains
Distribution: Fedora Core 1, Slackware 10.0 | 2.4.26 | custom 2.6.14.2, Slackware 10.2 | 11.0, Slackware64-13
Posts: 345

Rep: Reputation: 32
segfault with gcc, but not with TC


Consider the following program.
Code:
#include <stdio.h>
int main()
{
char *a = "Hello";
a[2] = 'a';
return 0;
}
This program compiles fine, without any error/warning messages. On TC it even executes okay(if I print the string pointed to by a, it prints Healo), however with gcc on execution it gives a segmentation fault.
Now I know that TC and gcc are different in some ways like :
1) TC uses 16 bit pointers while gcc uses 32 bit pointers
2) gcc conforms to the ansi version of C, more that TC
I may be wrong about these differences but this is what I know.

Whatever the differences may be, I could not understand why it gives the segfault error with gcc.
Help needed.
 
Old 04-20-2007, 12:31 PM   #2
wjevans_7d1@yahoo.co
Member
 
Registered: Jun 2006
Location: Mariposa
Distribution: Slackware 9.1
Posts: 938

Rep: Reputation: 30
In the implementation of C that's blowing up on you, constant strings such as the "Hello" are exactly that: constant. They are stored in a segment of memory which is marked read-only. This is not a bug; this is a feature. Consider this snippet:

Code:
char alpha;
char beta;

...

alpha="Hello";
beta="Hello";

alpha[2]='a';

printf("%s\n",beta);
Compilers can feel free to have alpha and beta pointing to the same string, because in theory it's constant. But unless the implementation puts that string in non-modifiable memory, you'll get "Healo" for beta.

If you want to be able to modify the string, do this:

Code:
alpha=strdup("Hello");
if(alpha==NULL)
{
  ... couldn't allocate the memory for the modifiable copy; blow up here
}
Hope this helps.
 
Old 04-20-2007, 05:08 PM   #3
koodoo
Member
 
Registered: Aug 2004
Location: a small village faraway in the mountains
Distribution: Fedora Core 1, Slackware 10.0 | 2.4.26 | custom 2.6.14.2, Slackware 10.2 | 11.0, Slackware64-13
Posts: 345

Original Poster
Rep: Reputation: 32
Thumbs up

Thanks a lot wjevans_7d1, that solved it completely. But now I have one more question. I tried the following code :
Code:
#include <stdio.h>
int main()
{
const int a=10;
int *b = &a;
*b=20;
printf("%d\n", a);
return 0;
}
when I compiled it, I got the following warning:
Code:
koodoo@knapsacker:~$ gcc prog.c -o prog
prog.c: In function `main':
prog.c:5: warning: initialization discards qualifiers from pointer target type
koodoo@knapsacker:~$
But when I executed it, I got the following result:
Code:
koodoo@knapsacker:~$ ./prog
20
koodoo@knapsacker:~$
How do I explain this now?
 
Old 04-20-2007, 05:57 PM   #4
AdaHacker
Member
 
Registered: Oct 2001
Location: Brockport, NY
Distribution: Kubuntu
Posts: 384

Rep: Reputation: 32
The "const" is the qualifier that's being discarded. Remove that and the warning will go away.

If you're asking why this prints 20, it's because the const only prevents you from changing the variable directly, e.g. by assignment. It doesn't necessarily make the variable unchangable through indirect means like pointers. If you want a truly unchangable constant, you can use a preprocessor define.
Code:
#define A 10
As an interesting side-note, if you pass the -O (for optimize) flag to GCC, this program will actually print out 10. This is probably because the constant is initialized at declaration, so GCC is inlining it at compile-time. It's also a good example of how you can't count on weird things like that to work every time.
 
Old 04-20-2007, 06:14 PM   #5
koodoo
Member
 
Registered: Aug 2004
Location: a small village faraway in the mountains
Distribution: Fedora Core 1, Slackware 10.0 | 2.4.26 | custom 2.6.14.2, Slackware 10.2 | 11.0, Slackware64-13
Posts: 345

Original Poster
Rep: Reputation: 32
k, thanks AdaHacker,
That's what I guessed, but as wjevans_7d1 pointed out for the previous case, shouldn't in this case also the 'a' be stored in a segment of memory which is marked read-only ?.
 
Old 04-20-2007, 07:36 PM   #6
AdaHacker
Member
 
Registered: Oct 2001
Location: Brockport, NY
Distribution: Kubuntu
Posts: 384

Rep: Reputation: 32
Should it? Probably. But that doesn't mean it will be. C leaves a lot up to the implementers, so you can't count on that sort of thing.
 
Old 04-21-2007, 10:30 AM   #7
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 36
This in effect overrides const because you are using indirection -
Code:
const int a=10;
int *b = &a;
*b=20;
Since this is implementation dependent (and a bad idea, too) the compiler is free to do what it wants. Since it did not segfault it probably located the contents of "a" to writable memory.

Consider:
Code:
const int a=10;
const int const *b = &a;
 
Old 04-21-2007, 10:03 PM   #8
kaz2100
Senior Member
 
Registered: Apr 2005
Location: Penguin land, with apple, no gates
Distribution: SlackWare > Debian testing woody(32) sarge etch lenny squeeze(+64) wheezy jessie stretch buster
Posts: 1,738

Rep: Reputation: 107Reputation: 107
Hya,

I agree
Quote:
C leaves a lot up to the implementers, so you can't count on that sort of thing.
Also, some compliers may optimize memory, like
Code:
Hi, I am a Penguin.
and
Code:
char *a = "Hi, I am a Penguin."
char *b = "Penguin."
and a points 'H', b points 'P' which is a[11]. In this case, if you modify b by whatever reason, a is also modified. I think "Segfault" happens, if you want to change it.

Happy Penguins!

Last edited by kaz2100; 04-23-2007 at 10:25 AM.
 
Old 04-23-2007, 09:57 AM   #9
koodoo
Member
 
Registered: Aug 2004
Location: a small village faraway in the mountains
Distribution: Fedora Core 1, Slackware 10.0 | 2.4.26 | custom 2.6.14.2, Slackware 10.2 | 11.0, Slackware64-13
Posts: 345

Original Poster
Rep: Reputation: 32
Thumbs up

Hi,

Thank You all very much. This thread helped clear a lot of my doubts.
 
Old 04-23-2007, 03:59 PM   #10
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by koodoo
k, thanks AdaHacker,
That's what I guessed, but as wjevans_7d1 pointed out for the previous case, shouldn't in this case also the 'a' be stored in a segment of memory which is marked read-only ?.
The string constant should be considered a pointer to an array of 'char' stored by the program temporarily wherever it finds appropriate. When initializing a 'char*' you copy that pointer. '10' is a literal constant, however when you use it to initialize an 'int' the value itself is copied and might never reside outside of a register or the variable it's assigned to (aside from the machine language of the function.) In other words, storing '10' in the same way you do a string literal would only make sense if you were doing something like this:
Code:
int *a = &10;
which doesn't make much sense.
ta0kira
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
firefox segfault yoyoguy2 Linux - Software 3 12-04-2006 05:54 PM
Why does this code segfault? Yerp Programming 11 07-15-2005 04:38 PM
SW9.1 (crnt) ATI 3.2.8 (gcc 3.3.3?) segfault error Aeiri Linux - Hardware 1 05-27-2004 04:56 PM
segfault with fglrx Vyeperman Linux - Hardware 0 04-18-2004 12:06 AM
Evolution SegFault granitepoint Linux - Software 0 01-12-2003 12:11 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:18 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration