Arjun
Arjun

Reputation: 907

Strings with malloc in C

I am writing a very simple program to copy a string using malloc.

#include <stdio.h> 
#include <stdlib.h> 

char * copyStr(char s[])
    {
      int len = strlen(s); //find length of s
      char * copy; 
      copy = (char *)malloc(len); //dynamically allocate memory 
      int i; 
      for(i=0;i<len;i++) 
       {
         copy[i]=s[i];  //copy characters               
       }
       return copy; //return address
    }

int main(int argc, char ** argv)
    {
     char * str;
     str = "music is my aeroplane";
     char * res;
     res = copyStr(str);
     printf("The copied string is : %s",res);
     getch();
    }

The desired output is:

The copied string is : music is my aeroplane

The current output is:

The copied string is : music is my aeroplaneOMEeJ8«≤╝

Any advice is appreciated.

Upvotes: 3

Views: 18391

Answers (2)

Lacobus
Lacobus

Reputation: 1658

Strings in C are null-terminated.

The C programming language has a set of functions implementing operations on strings (character strings and byte strings) in its standard library. Various operations, such as copying, concatenation, tokenization and searching are supported. For character strings, the standard library uses the convention that strings are null-terminated: a string of n characters is represented as an array of n + 1 elements, the last of which is a "NUL" character.

In this case, you should have enough memory to store the original string contents and the "NUL" character (length+1). And don't forget to ensure the presence of the "NUL" character after the end of the string.

There are many possible ways to implement char * copyStr(char[]) function:

1) Your way (corrected):

char * copyStr(char s[])
{
    int i;
    size_t len = strlen( s );

    char * p = (char*) malloc( len + 1 );

    for( i = 0; i < len; i++ )
        p[i] = s[i];

    p[i] = '\0';

    return p;
}

2) Using memcpy():

char * copyStr(char s[])
{
    size_t len = strlen( s );

    char * p = (char*) malloc( len + 1 );

    memcpy( p, s, len );

    p[ len ] = '\0';

    return p;
}

3) Using strcpy():

char * copyStr(char s[])
{
    size_t len = strlen( s );
    char * p = (char*) malloc( len + 1 );
    strcpy( p, s );
    return p;
}

4) Using strdup():

char * copyStr(char s[])
{
    return strdup(s);
}

Note: For every malloc() function call you need a free() function call, your main() needs a little modification for correctness:

int main( int argc, char ** argv )
{
    char * str;
    char * res;

    str = "music is my aeroplane";

    res = copyStr( str );

    printf( "The copied string is : %s", res );

    free(res); /* freedom */

    getch();

    return 0;
}

Hope it Helps!

Upvotes: 6

Boiethios
Boiethios

Reputation: 42749

A C string is null terminated. Add a null character (ie the char which ASCII code is 0) at end of the string :

char * copyStr(char s[])
{
  size_t len = strlen(s); //find length of s
  char * copy; 
  copy = (char *)malloc(len + 1); //dynamically allocate memory
                           /* One more char must be allocated for the null char */

  size_t i; 
  for(i=0;i<len;i++) 
   {
     copy[i]=s[i];  //copy characters               
   }
   copy[i] = '\0'; // HERE
   return copy; //return address
}

It is better to use size_t for the lengths because it is unsigned.

Upvotes: 8

Related Questions