ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
/* 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!
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.
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.
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.
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).
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.
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).
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.
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.
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.
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).
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.