-2

A string constant in C can be initialized in two ways: using array and a character pointer;

Both can access the string constant and can print it;

Coming to editing part, if I want to edit a string that is initialized using arrays, it is straight forward and we can edit using array individual characters.

If I want to edit a string that is initialized using character pointer, is it impossible to do?

Let us consider the following two programs:

Program #1:

#include<stdio.h>

void str_change(char *);

int main()
{
    char str[] = "abcdefghijklm";

    printf("%s\n", str);
    str_change(str);
    printf("%s\n", str);

    return 0;
}

void str_change(char *temp)
{
    int i = 0;

    while (temp[i] != '\0') {
    temp[i] = 'n' + temp[i] - 'a';
    i++;
}
}

Program #2:

#include<stdio.h>

void str_change(char *);

int main()
{
    char *str = "abcdefghijklm";

    printf("%s\n", str);
    str_change(str);
    printf("%s\n", str);

    return 0;
}

void str_change(char *temp)
{
    int i = 0;

    while (temp[i] != '\0') {
        temp[i] = 'n' + temp[i] - 'a';
        i++;
    }
}

I tried the following version of function to program #2, but of no use

void str_change(char *temp)
{
        while (*temp != '\0') {
                *temp = 'n' + *temp - 'a';
                temp++;
        }
}

The first program is working pretty well,but segmentation fault for other, So, is it mandatory to pass only the string constants that are initialized using arrays between functions, if editing of string is required?

hanugm
  • 1,127
  • 3
  • 13
  • 44
  • 2
    Your question is a simplified version of https://stackoverflow.com/questions/2245664/what-is-the-type-of-string-literals-in-c-and-c. – Dave M. Aug 14 '17 at 04:10

3 Answers3

0

String literals are stored in static duration storage which exist for program lifetime and could be read only. Changing content of this literal leads to undefined behavior.

Copy this literal to modificable array and pass it to function.

char array[5];
strcpy(array, "test");

If you are declaring pointer to string literal, make it const so compiler Will warn you if you try to modify it.

const char * ptr = " string literal";
kocica
  • 6,412
  • 2
  • 14
  • 35
0

I think, because if you use pointer, you can only read this array, you can't write anything to there with loop, because elements of your array don't situated nearly. (Sorry for my English)

0

So it is mandatory to pass only the string constants that are initialized using arrays between functions, if editing of string is requiredc?

Basically, yes, though the real explanation is not these exact words. The following definition creates an array:

char str[] = "abc";

this is not a string literal. The "abc" token is a string literal syntax, not a string literal object. Here, that literal specifies the initial value for the str array. Array objects are modifiable.

char *str = "abc";

Here the "abc" syntax in the source code is an expression denoting a string literal object in the translated program image. It's also a kind of array, with static storage duration (regardless of the storage duration of str). The "abc" syntax evaluates to a pointer to the first character of this array, and the str pointer is initialized with that pointer value.

String literals are not required to support modification; the behavior of attempting to modify a string literal object is undefined behavior.

Even in systems where you don't get a predictable segmentation fault, strange things can happen. For instance:

char *a = "xabc";
char *b = "abc";

b[0] = 'b';  /* b changes to "bbc" */

Suppose the assignment works. It's possible that a will also be changed to "xbbc". A C compiler is allowed to merge the storage of identical literals, or literals which are suffixes of other literals.

It doesn't matter whether or not a and b are close together; this sneaky effect could occur even between distant declarations in different functions, perhaps even in different translation units.

String literals should be considered to be part of the program's image; a program which successfully modifies a string literal is effectively self-modifying code. The reason you get a "segmentation fault" in your environment is precisely because of a safeguard against self-modifying code: the "text" section of the compiled program (which contains the machine code) is located in write-protected pages of virtual memory. And the string literals are placed there together with the machine code (often interspersed among its functions). Attempts to modify a string literal result in write accesses to the text section, which are blocked by the permission bits on the pages.

In another kind of environment, C code might be used to produce a software image which goes into read-only memory: actual ROM chips. The string literals go into the ROM together with the code. Attempting to modify one adds up to attempting to modify ROM. The hardware might have no detection for that. For instance, the instruction might appear to execute, but when the location is read back, the original value is still there, not the new value. Like the segmentation fault, this is within the specification range of "undefined behavior": any behavior is!

Kaz
  • 55,781
  • 9
  • 100
  • 149