Storage for Strings in C

In C, a string can be referred either using a character pointer or as a character array.

Strings as character arrays

char str[4] = "GfG"; /*One extra for string terminator*/
/*    OR    */
char str[4] = {‘G’, ‘f’, ‘G’, '\0'}; /* '\0' is string terminator */

When strings are declared as character arrays, they are stored like other types of arrays in C. For example, if str[] is an auto variable then string is stored in stack segment, if it’s a global or static variable then stored in data segment, etc.

Strings using character pointers
Using character pointer strings can be stored in two ways:

1) Read only string in a shared segment.
When string value is directly assigned to a pointer, in most of the compilers, it’s stored in a read only block (generally in data segment) that is shared among functions.

  
  char *str  =  "GfG";  

In the above line “GfG” is stored in a shared read only location, but pointer str is stored in a read-write memory. You can change str to point something else but cannot change value at present str. So this kind of string should only be used when we don’t want to modify string at a later stage in program.

2) Dynamically allocated in heap segment.
Strings are stored like other dynamically allocated things in C and can be shared among functions.

  char *str;
  int size = 4; /*one extra for ‘\0’*/
  str = (char *)malloc(sizeof(char)*size);
  *(str+0) = 'G'; 
  *(str+1) = 'f';  
  *(str+2) = 'G';  
  *(str+3) = '\0';  



Let us see some examples to better understand above ways to store strings.

Example 1 (Try to modify string)
The below program may crash (gives segmentation fault error) because the line *(str+1) = ‘n’ tries to write a read only memory.

int main()
{
 char *str; 
 str = "GfG";     /* Stored in read only part of data segment */
 *(str+1) = 'n'; /* Problem:  trying to modify read only memory */
 getchar();
 return 0;
}

Below program works perfectly fine as str[] is stored in writable stack segment.

int main()
{
 char str[] = "GfG";  /* Stored in stack segment like other auto variables */
 *(str+1) = 'n';   /* No problem: String is now GnG */
 getchar();
 return 0;
}

Below program also works perfectly fine as data at str is stored in writable heap segment.

int main()
{
  int size = 4;

  /* Stored in heap segment like other dynamically allocated things */
  char *str = (char *)malloc(sizeof(char)*size);
  *(str+0) = 'G'; 
  *(str+1) = 'f';  
  *(str+2) = 'G';    
  *(str+3) = '\0';  
  *(str+1) = 'n';  /* No problem: String is now GnG */
   getchar();
   return 0;
}     

Example 2 (Try to return string from a function)
The below program works perfectly fine as the string is stored in a shared segment and data stored remains there even after return of getString()

char *getString()
{
  char *str = "GfG"; /* Stored in read only part of shared segment */

  /* No problem: remains at address str after getString() returns*/
  return str;  
}     

int main()
{
  printf("%s", getString());  
  getchar();
  return 0;
}

The below program alse works perfectly fine as the string is stored in heap segment and data stored in heap segment persists even after return of getString()

char *getString()
{
  int size = 4;
  char *str = (char *)malloc(sizeof(char)*size); /*Stored in heap segment*/
  *(str+0) = 'G'; 
  *(str+1) = 'f';  
  *(str+2) = 'G';
  *(str+3) = '\0';  
  
  /* No problem: string remains at str after getString() returns */    
  return str;  
}     
int main()
{
  printf("%s", getString());  
  getchar();
  return 0;
}

But, the below program may print some garbage data as string is stored in stack frame of function getString() and data may not be there after getString() returns.

char *getString()
{
  char str[] = "GfG"; /* Stored in stack segment */

  /* Problem: string may not be present after getSting() returns */
  return str; 
}     
int main()
{
  printf("%s", getString());  
  getchar();
  return 0;
}

Please write comments if you find anything incorrect in the above article, or you want to share more information about storage of strings





  • sachin

    Read only segment is part of text segment or oart of data segment

  • http://practicepeople.blogspot.in/ RajKumar Rampalli

    I am getting correct output (returning string from other function ) even after this string is defined using character array.
    The memory of stack segment of function should be cleared when it returns.
    Why we are seeing the output ? can anyone please help me in understanding it ?


    #include
    char* character_pointer_fun()
    {
    char *str = "Using character pointer";
    return str;
    }
    char* character_array_fun()
    {
    char str[] = "Using character array";
    str[1] = 'S';
    return str;
    }
    int local_var()
    { int a =111;
    return a;
    }
    void main()
    {
    char *char_ptr_str;
    char *char_array_str;
    int a;
    char_ptr_str = character_pointer_fun();
    printf("In main: %sn", char_ptr_str);
    char_array_str = character_array_fun();
    printf("In main: %sn", char_array_str);
    a = local_var();
    printf("In main: local var: %dn", a);
    }

    Output:

    In main: Using character pointer

    In main: USing character array /* Not expected output */

    In main: local var: 111 /* Not expected output */

  • abhishek

    ok if char* str=”ABCD” goes to ReadOnlyMemory
    then consider the following code and explain please

    char* str=”ABCD”;
    str[2]=’Z';

    it works
    so my question is if the ABCD is in READ ONLY MEMORY then how Z is assigned at the 2th position
    any help would be great , thanks in advance

    • Keshav Sharma

      #include
      int main()
      {
      char* str=”ABCD”;
      str[2]=’Z';
      printf(“%s”,str);
      getchar();
      return 0;
      }

      I tried it but it didnt worked..

    • adi

      in gcc compiler it gives segmentation fault….

    • Zhang Dongdong

      I don’t believe this works!!! which compiler have you try?

  • sai

    sory sir i didn’t got it ,,plz explain once.
    if str is dynamically created.then
    str=”yes”.//no prob then assign new string
    str=”answer”//no problem,valid then if we try to change the first char from previous assigned str like
    *(str+1)=’b’//error
    why….

    • Prashanth

      when you do str=”yes” . “yes” is allocated memory in Read Only data segment and str contains address of this.

      Now when you do str=”answer” , “answer” is allocated memory in Read Only data segment and str contains address of this.

      so now when you try to change the string by doing *(str+1)=’b’ you will get segmentation fault as you are trying to change the string stored in read only data memory

  • numid

    Very helpful post

     
    
     
  • abc

    if we have allocated a string dynamically like str=(char*)malloc(sizeof(char*)*4) and then do str = “abc”. If we now try to change one of the characters then does it give a segmentation fault. In the case str is in heap right?

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
    • rajender

      No. You can’t say fo sure that str is stored in heap. it is a pointer pointing to the memory in heap but not itself is in heap.

      As you do str = “abc”, you pointing str to a RO data segment, so modifying data through str will give segfault.

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
      • sai

        sory sir i didn’t got it ,,plz explain once.
        if str is dynamically created.then
        str=”yes”.//no prob then assign new string
        str=”answer”//no problem,valid then if we try to change the first char from previous assigned str like
        *(str+1)=’b’//error
        why….

         
        /* Paste your code here (You may delete these lines if not writing code) */
         
        • Ashish kumar

          Actually,using malloc() you did allocated the memory in heap and at that time str was
          pointing to that memory.

          But the moment you assigned str to “abc” which is stored in read only section ,str starts pointing to the read only section and modifying it definitely will cause segmentation fault.

           
          /* Paste your code here (You may delete these lines if not writing code) */
           
    • Prashanth

      When you do this str=(char*)malloc(sizeof(char*)*4) , memory is allocated in the heap and str has address for that location . But when you do str = “abc” , “abc” is allocated memory in Read Only data segment and str has address to that location. So u cant modify the string , u will get segmentation fault . And str is not on the heap , if its an auto variable then it is in stack , if its a global variable then it is in Data segment.

  • Arif

    A very nice post!

  • Ricky13

    Awesome post! Really nice explanations.

  • Sidharth

    Awesome post….great work
    u cant really find these things in textbooks!!!!

  • Tushar
     
    Nice post ... I have a query ...
    char *getString()
    {
      char str[] = "GfG"; /* Stored in stack segment */
      return str;
    } 
    Here whats the scope of "str" , means - how long it will be there in meomory ,  and when memory will be freed for the same ? 
     
    • RajKumar Rampalli

      >>>Here whats the scope of “str” , means – how long it will be there in memory , and when memory will be freed for the same ?
      The value of str is present in the stack memory, so once the function getString() is done its task, the data belongs to this function (str value) will be cleared from stack. So, Answer to your question is the memory is cleared when getString executes return statement.

  • avnish.tyagi87

    Concept clearing post!! thanks..

  • sharat

    great post! Thanks

  • seeker7

    awesome post!
    good job! :)

  • Venki

    Guys, try the following code in Borland compiler,

     #include<stdio.h>
    
    int main()
    {
    char *p="abcde";
    *(p+1) = 'd';
    printf("%c", *(p+1));
    
    return 0;
    } 
  • yogi

    nice explanation of constant literals storage in read only block of data segment. Good efforts….

  • Sandeep

    @justGautam: Since you have the statements outside functions, both str1 and str2 become global, so both can be accessed in all the functions.

    Unlike str1, str2 is stored in a read only block, so data at str2 can not be modified.

  • justGautam

    So if I have the following C statements outside the main() or any other C function,

    char str1[] = “GfG”;
    char *str2 = “GfG”;

    what would be the difference in str1 and str2?

    • Tracy

      you mean both of them are global variables.if that is the case,string literals “GfG” is stored in the data segments.
      in my opinion,there is no diiference,or you can write a program to verify.Hope this helps!

      • http://www.iresearchlab.com iRL

        I think they are not same. First string can be changed using str1 while second can not be. The memory for first “GFG” will come from rw DS.

         
        /* Paste your code here (You may delete these lines if not writing code) */
         
        • sapnasirivsl

          str1’s “GFG” will be stored in the read write data segment and the str2’s “GFG” will be stored in read only data seg.

           
          /* Paste your code here (You may delete these lines if not writing code) */
           
          • https://www.facebook.com/priya.arora.77 Pinnacle

            Ya @iRL , you are right as the memory scope will change only but characteristics of array n string for change will remain same…

             
            /* Paste your code here (You may delete these lines if not writing code) */
             
    • Prashanth

      str1[] is stored in writable stack segment. so u can modify the string like str1[1] = ‘a’ but incase of str2 , “GfG” is allocated memeory in read only DS . so u can’t change the string , doing this str2[1] = ‘a’ will give segmentation fault.

      The reason is that in the first case “GfG” is allocated memeory in stack and hence can be modified. But in the second case you can’t

  • GeeksforGeeks

    @devendraiiit: Thanks for pointing out the issue. We have made changes to include ‘\0′ in all the strings.

  • devendraiiit

    One of the best post for understanding basic of Strings.

    But I think in your example “Dynamically allocated String” you should have to put ‘/0′ at the back. Overall nice effort.

    :)