1

This porgram prints different permutations of a string.It works correctly if I declare string as char array in main and pass array name in printAnagram function.But if I declare string as char* s = "hello" and pass 's' then it crashes. Why?

#include <stdio.h>
#include <conio.h>

void printAnagram(char *str, int b, int e);

int main()
{
    char *s = "ABC"; // works fine when char s[] = "ABC" is used.
    printAnagram(s, 0, 2);
    return 0;
}

void swap(char *a, char* b)
{
    char temp = *a;
    *a = *b;
    *b = temp;
}
void printAnagram(char *str, int b, int e)
{
    int i = 0;
    if(b==e)
        printf("%s\n", str);
    else
    {
        for(i=b;i<=e;i++)
        {
            swap((str+b),(str+i));
            printAnagram(str, b+1, e);
            swap((str+b), (str+i));
        }
    }
}
Infinity
  • 165
  • 1
  • 1
  • 7

5 Answers5

3

In char *s = "ABC"; - "ABC" is a string literal modifying it is UB.

Pointers are usually used to point to data that already exists, so you can use it like this

char arr[] = "C__";

char* t = &arr[0];

Also modifiable,

t[1] = 'p';

t[2] = 'p';

Here

char *t= "C__";

points to a string constant.

There is a better way of writing the above:

const char* t= "C__"; 
Sadique
  • 22,572
  • 7
  • 65
  • 91
  • @Sadique I try this approach and when I send the char* t to the function, the arr[] does not change. Any ideas? – JC203 Apr 06 '18 at 18:39
2

The crash has to do with the kind of memory where the characters of your string are stored, not with whether or not you declare it as a character array or a pointer. In other words, you can keep the pointer, and copy the string into it, like this:

int main()
{
    char *s = strdup("ABC");
    printAnagram(s, 0, 2);
    free(s);
    return 0;
}

C standard considers memory allocated to string literals, such as "ABC", non-writable. Hence, any changes you do to them cause undefined behavior. When you change declaration to an array, C copies the literal into writable memory, so there is no undefined behavior (and no crash).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

char *s = "ABC"; is a string literal stored in read only memory location. When you try modifying it, yes it will crash. In fact it is of const char *s. Instead you should be using as mentioned already as,

char s[] = "ABC"; 

Look at this previous SO answer Modifying a string literal.

Community
  • 1
  • 1
Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
0

You are accessing the read only memory.

char *a="ABC";// It will stored in the read only memory. 

If you are trying to access this you cannot do. You can use like this.

char array[]="ABC";
char *a=array;
Karthikeyan.R.S
  • 3,991
  • 1
  • 19
  • 31
0

You could try to declare a char array, for example char [6] str="ABC"; and then use a char pointer, to manage that array: char *p=&str; The crash is due to the fact that your pointer to a string that is not present in the stack memory.

capagira87
  • 56
  • 1
  • 6