Search code examples
cstringmallocdynamic-memory-allocationgarbage

Malloc or Calloc return unexpected values in string


I am trying to create a dynamic memory allocation string so which returns a string removing all vowels. In the beginning, some of the strings work correctly but suddenly some of them returns with an extra value which makes me fail the test, and I am failing to complete the task. Here is the code:

    #include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *disemvowel(const char *str)
{
  char buf[100];
  unsigned long i,j=0,nextsize=0;
  for(i=0;i<strlen(str);i++)
  {
   if(*(str+i)=='a' || *(str+i)=='A' || *(str+i)=='e' || *(str+i)=='E' || *(str+i)=='i' || *(str+i)=='I' || *(str+i)=='o' || *(str+i)=='O' || *(str+i)=='u' || *(str+i)=='u') continue;
   else{
        buf[j]=str[i];
        j++;
        nextsize++;
   }
  }
  char *disemvoweStr=(char *) malloc((nextsize)*sizeof(char));
  strcpy(disemvoweStr,buf);
  printf("\nProblem=");
  puts(str);
  printf("\nSolution");
  puts(disemvoweStr);
  return disemvoweStr;
}

Some of them are working and return correct answer like:

Problem=This website is for losers LOL!

SolutionThs wbst s fr lsrs LL!

Problem=No offense but, Your writing is among the worst I've ever read

SolutionN ffns bt, Yr wrtng s mng th wrst 'v vr rd

Problem=What are you, a communist?

Solution=Wht r y, cmmnst?

But then some of them return garbage values and test fails= Problem=Yyy!

SolutionYyy!�

Problem=mVcoyIbLyAOpsOzRhwQUiWlwRHuhjUQDMBVSLelPRGrhzWagWhJzCVssmjQoFyLZVOxc

SolutionQQmTvvWfspPLzfNgNRGfcVrTMTtdtFNjKwmpdwbvNFXmUjydZCUxwmyYbsZfrwCmrbMzknqTNJdchjgMYHcPfUVNdHPRjbcgmVcybLyps���

Any idea why I am getting ��� at the end? What is the solution and reason for this error? Please help me


Solution

  • You don't null terminate the buffer. Therefore strcpy wil just copy the contents of buf until a null character is encountered which is undefind behaviour.

    Add this right after the forloop:

    buf[j] = 0;
    

    Also in malloc((nextsize) * sizeof(char)), nextsize doesn't include the null character. Actually you don't need nextsizeat all, because it just mirrors j. So you should just have:

    char* disemvoweStr = malloc(j + 1);
    

    BTW, the (char*) cast is not needed, and sizeof(char) is 1 by definition.