Search code examples
cstructscopeconcatenationc-strings

character array is not working as expected (concatenation of two arrays)


#include <stdio.h>

typedef struct _Text { 
  char *str; //pointer to string
  int length; //length of the text
  int counter; //counter of text pointing this struct
  } *Text;

  Text concat(Text txt1, Text txt2){
    Text txt= malloc(sizeof(*txt));
    txt->length=txt1->length+txt2->length; 
    txt->counter=1;

    char str[txt->length];
    
    for(int i=0; txt1->length>i;i++){ //first word concat
      str[i]=txt1->str[i];
      }
    
    for(int i=0; txt2->length>i;i++){ //second word concat
      str[i+txt1->length]=txt2->str[i];
      }
    txt->str=str;
    return txt;
      }

int main(void) {
  
  Text txt= malloc(sizeof(*txt));
  Text txt1= malloc(sizeof(*txt1));
  txt->str="hello"; txt->length=5; txt->counter=1;
  txt1->str="lo"; txt1->length=2; txt1->counter=1;
  concat(txt,txt1);
  
  return 0;
}

The return value of concat is not the value it should be, it seems like it is not saving the value of str, the correct return should be "hellolo", but it returns "hello"


Solution

  • The pointer text->str returned from the function is invalid because it is a pointer to the local array str declared within the function that will not be alive after exiting the function

    char str[txt->length];
    //...    
    txt->str=str;
    return txt;
    

    Also there is a logical inconsistence. The pointers txt->str and txt1->str point to strings

    txt->str="hello";
    txt1->str="lo"
    

    but the pointer txt->str does not point to a string because the array str within the function does not build a string.

    Instead of the local array str you heave to allocate dynamically an array that will be pointed to by txt->str. For example

    txt->str = malloc( text->length + 1 );
    

    Pay attention to that such a typedef declaration

    typedef struct _Text { 
      char *str; //pointer to string
      int length; //length of the text
      int counter; //counter of text pointing this struct
      } *Text;
    

    only confuses readers of the code because in a declaration like this

    Text concat(Text txt1, Text txt2){
    

    it is unclear that the name Text denotes a pointer type.