Search code examples
c++dynamic-memory-allocationc-stringsstring-concatenationfunction-definition

C++ program not returning a Value (Functions)


I want to write a program, to create a function that concatenates two strings to form a single string. However, my program is not returning any value.

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

char* my_str_cat( char* s1, char* s2, char* combined ){
   for(int i = 0;i<strlen(s1);i++){
       combined[i]=s1[i];
   }
   for (int j=0;j<strlen(s2);j++){
       combined[strlen(s1)+j]=s2[j];
   }
   return combined;
}

int main(){
   char s1[100];
   char s2[100];
   char** combined = new char*;
   cout<<"Enter s1: "<<endl;
   cin.getline(s1,100);
   cout<<s1<<endl;
   cout<<"Enter s2: "<<endl;
   cin.getline(s2,100);
   my_str_cat(s1,s2,*combined);
   delete combined;
   
   return 0;
}

Solution

  • This declaration

    char** combined = new char*;
    

    declares a pointer of the type char ** that points to an allocated memory for an object of the type char *.

    Dereferencing this pointer in this call

    my_str_cat(s1,s2,*combined);
    

    passes an uninitialized pointer of the type char * to the function my_str_cat.

    And within the function this uninitialized pointer is used to access a memory that results in undefined behavior.

    You need to allocate a memory for a character array large enough to store two concatenated C strings forming a new C string.

    You could allocate the memory within the function itself.

    The function can look the following way as it is shown in the demonstrative program below.

    #include <iostream>
    #include <iomanip>
    #include <cstring>
    
    char * my_str_cat( const char *s1, const char *s2 )
    {
        size_t n1 = std::strlen( s1 );
        
        char * result = new char[n1 + std::strlen( s2 ) + 1];
        
        std::strcpy( std::strcpy( result, s1 ) + n1, s2 );
        
        return result;
    }
    
    int main() 
    {
        const size_t N = 100;
        char s1[N];
        char s2[N];
        
        std::cout << "Enter s1: ";
        
        std::cin.getline( s1, sizeof( s1 ) );
        
        std::cout << "Enter s2: ";
        
        std::cout << std::noskipws;
        
        std::cin.getline( s2, sizeof( s2 ) );
        
        char *combined = my_str_cat( s1, s2 );
        
        std::cout << combined << '\n';
        
        delete []combined;
        
        return 0;
    }
    

    The program output might look like

    Enter s1: Hello
    Enter s2:  World!
    Hello World!
    

    Another approach of declaring and defining the function is when it is the user of the function that is responsible to supply the result character array to the function that will contain two concatenated strings.

    For example

    #include <iostream>
    #include <iomanip>
    #include <cstring>
    
    char * my_str_cat( char *result, const char *s1, const char *s2 )
    {
        return std::strcat( std::strcpy( result, s1 ) , s2 );
    }
    
    int main() 
    {
        const size_t N = 100;
        char s1[N];
        char s2[N];
        
        std::cout << "Enter s1: ";
        
        std::cin.getline( s1, sizeof( s1 ) );
        
        std::cout << "Enter s2: ";
        
        std::cout << std::noskipws;
        
        std::cin.getline( s2, sizeof( s2 ) );
        
        char *combined = new char[std::strlen( s1 ) + std::strlen( s2 ) + 1];
    
        std::cout << my_str_cat( combined, s1, s2 ) << '\n';
        
        delete []combined;
        
        return 0;
    }
    

    The program output might look the same way as it is shown for the previous demonstrative program that is

    Enter s1: Hello
    Enter s2:  World!
    Hello World!
    

    Without using standard string functions and using only loops the function can be defined the following way.

    char * my_str_cat( char *result, const char *s1, const char *s2 )
    {
        char *p = result;
        
        while ( *s1 ) *p++ = *s1++;
        
        while ( ( *p++ = *s2++ ) );
    
        return result;
    }