LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
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 03-05-2008, 05:11 PM   #1
bulkathos
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Rep: Reputation: 0
about array and pointer in c


/* in my source file */
#include <stdio.h>
void squeeze(char *ptr1, char *ptr2);
main()
{
char s1[] = "This is a programe for testing squeeze!"; /*my question */
char s2[] = "abcdef"; /* is about these two lines */
printf("s1=%s\n",s1);
printf("s2=%s\n",s2);
squeeze(s1,s2);
printf("After call squeeze s1=%s\n",s1);
}
void squeeze(char *s1, char *s2)
{
int i;
int j;
int k;
int c;
for (k = 0;(c = *(s2+k)) != '\0'; k++)
{
for (i = j = 0; *(s1+j) != '\0';j++)
{
if(*(s1+j) != c)
{
*(s1+i) = *(s1+j);
i++;
}
}
*(s1+i) = '\0';
}
}

it works,
but if i replace line 5 and 6 with:
char *s1 = "This is a programe for testing squeeze!";
char *s2 = "abcdef";
i will get the error :
Segmentation fault
why?
thanks!

Last edited by bulkathos; 03-05-2008 at 05:13 PM.
 
Old 03-05-2008, 05:48 PM   #2
cmnorton
Member
 
Registered: Feb 2005
Distribution: Ubuntu, CentOS
Posts: 585

Rep: Reputation: 35
Pointer To Array With No Storage

char s1[] = "This is a programe for testing squeeze!"; /*my question */
char s2[] = "abcdef"; /* is about these two lines */

Using s1 as the example, you are saying you have an array of characters. C allows you to eliminate the array length (a number in between '[' and ']'), because you are declaring the length by initializing each array with a string.

When you place a "*" in front char *s1[], you are in fact saying this is an array of pointers to strings. The storage for those strings is not implied.
 
Old 03-05-2008, 06:56 PM   #3
fantas
Member
 
Registered: Jun 2007
Location: Bavaria
Distribution: slackware, xubuntu
Posts: 143

Rep: Reputation: 22
They should actually compile to the same code, so I don't see an error there either. It would be interesting to see what the assembler output of this piece of code would be.
Are you sure the code that you posted is exactly the one you're using ?

I wonder if it makes a difference if you put a "const" before the arrays (and in the squeeze functions parameters) ... , i.e. "const char[]" or "const char *".

PS: cmnorton, you need new glasses, there is no array to char pointers anywhere in the code.
 
Old 03-05-2008, 07:23 PM   #4
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by bulkathos View Post
but if i replace line 5 and 6 with:
char *s1 = "This is a programe for testing squeeze!";
char *s2 = "abcdef";
i will get the error :
Segmentation fault
why?
In ANSI C, string literals are not writable (but character arrays initialized to string literals are). In some older version of gcc, there was an -fwritable-strings flag to give the behavior you expect. It has since been removed since most legacy software has been updated accordingly.
 
Old 03-05-2008, 07:25 PM   #5
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by fantas View Post
They should actually compile to the same code
No they shouldn’t. In the first you have a character array initialized to a string literal, in the second you have a pointer to the first character of a string literal (the string literal itself can be in read-only memory).
 
Old 03-05-2008, 07:30 PM   #6
fantas
Member
 
Registered: Jun 2007
Location: Bavaria
Distribution: slackware, xubuntu
Posts: 143

Rep: Reputation: 22
Ah, ok, I overlooked actually the part that there's something actually written into the string later (thought it just did some comparisons).
 
Old 03-05-2008, 08:15 PM   #7
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Here's the difference:
  • char[] - This is the definition of an array, which has a stack size of the sum of all of its elements'. For convenience, the name of the variable implicitly means the pointer to its first element. The string constant is copied directly onto the stack to create the array, making it available until the variable goes out of scope. No future definitions in the same scope will overwrite the array and it remains writable.

  • char* - This is a pointer to any single character, which could be the first element of an array. It has the same stack size as a pointer regardless of if it's initialized with a string constant or not. For this to happen, internal memory must be used to store the string constant. This memory may or may not be writable. Normally with gcc it isn't writable, giving you a segfault when you try. Additionally, the internal memory is finite so subsequent uses of char* with string constants might overwrite older ones.
ta0kira

Last edited by ta0kira; 03-05-2008 at 08:43 PM.
 
Old 03-06-2008, 06:22 AM   #8
bulkathos
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by osor View Post
No they shouldn’t. In the first you have a character array initialized to a string literal, in the second you have a pointer to the first character of a string literal (the string literal itself can be in read-only memory).
i see
thanks
 
Old 03-06-2008, 07:54 AM   #9
cmnorton
Member
 
Registered: Feb 2005
Distribution: Ubuntu, CentOS
Posts: 585

Rep: Reputation: 35
Vision not what it used to be

Quote:
Originally Posted by fantas View Post
They should actually compile to the same code, so I don't see an error there either. It would be interesting to see what the assembler output of this piece of code would be.
Are you sure the code that you posted is exactly the one you're using ?

I wonder if it makes a difference if you put a "const" before the arrays (and in the squeeze functions parameters) ... , i.e. "const char[]" or "const char *".

PS: cmnorton, you need new glasses, there is no array to char pointers anywhere in the code.
Mea Culpa, I thought char *s1[] had been written. I need a bigger magnifying glass.
 
Old 03-06-2008, 09:16 AM   #10
fantas
Member
 
Registered: Jun 2007
Location: Bavaria
Distribution: slackware, xubuntu
Posts: 143

Rep: Reputation: 22
Talking

No worries. As seen, I need to improve my own reading skills as well ...
 
Old 03-06-2008, 01:36 PM   #11
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by ta0kira View Post
Normally with gcc it isn't writable, giving you a segfault when you try.
Let me clarify that this is not just a gcc-ism—the standard states that modifying a string literal results in undefined behavior.

See §6.4.5.5, §6.4.5.6, and §6.7.8.14 for the relevant information.
 
Old 03-06-2008, 01:43 PM   #12
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Yes, you're right but "undefined" doesn't mean "not allowed." Some implementations allow it so if OP compiled on such a system (that could still be compliant in that area) it might actually work.
ta0kira

PS The memory map generally has to have the memory marked as "read only" for it to cause a segfault, but compilers of lesser quality don't always do that.

Last edited by ta0kira; 03-06-2008 at 01:46 PM.
 
Old 03-07-2008, 11:08 AM   #13
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by ta0kira View Post
PS The memory map generally has to have the memory marked as "read only" for it to cause a segfault, but compilers of lesser quality don't always do that.
Btw, this has interesting consequences. There are some archs for which gcc targets have been implemented where the arch doesn’t have a read-only section assembly instruction. You would think that this means that you can run freely with writing to string literals, but there are some subtle problems.

For example, on those archs, the following code:
Code:
#include <stdio.h>

int main()
{
        char *str1 = "World.";
        str1[0] = 0;
        char str2[] = "Hello, World.";

        puts(str2);

        return 0;
}
Will will have the output “Hello, ” since the initialization of the char array occurs after the original string is modified (of course this occurs since GCC will use the same storage for string literals which overlap in such a way, which is an unspecified feature in the standard).
 
Old 03-07-2008, 12:27 PM   #14
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
That's very interesting! I kind of wish my computer did that so I could mess with it.
ta0kira
 
Old 05-18-2009, 04:10 AM   #15
Alien_Hominid
Senior Member
 
Registered: Oct 2005
Location: Lithuania
Distribution: Hybrid
Posts: 2,247

Rep: Reputation: 53
Why does it print "Hello, "?

I understand it incorrectly (so please explain):

1st step: World.0 is placed at the start of memory segment. str1's value is its address.
2nd step: First char (byte) of World0 is changed into 0 byte. We have 0orld.0 .
3rd step: Hello, World.0 is placed into the same memory location as str1 points to, because gcc uses same storage without remembering what was placed there before. str2 is the same as str1 value.
Code:
0orld.0*******  *   - garbage
||||||||||||||
Hello, World.0  " " - space
If the above is correct (which is not), then I have no idea why puts(str2) prints "Hello, ".

Last edited by Alien_Hominid; 05-18-2009 at 04:12 AM.
 
  


Reply



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
Can't pass 2d-array-class-pointer Bariton Programming 3 09-11-2007 08:30 AM
number of element in a array of pointer? os2 Programming 7 03-09-2005 11:50 AM
about array and pointer seeLnd Programming 5 05-30-2004 07:56 AM
sending pointer array to function marek Programming 4 04-15-2004 04:46 PM
pointer to a 2D array dhanakom Programming 7 09-07-2003 04:22 AM

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

All times are GMT -5. The time now is 06:57 AM.

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