Home > Mobile >  Can someone please explain why I'm getting a seg fault error
Can someone please explain why I'm getting a seg fault error

Time:06-28

This code compiles successfully but when I debug it shows a SIGSEV seg fault error. Can someone help please?

char *_strdup(char *str)
{
   int i, size = 0;
   char *mp;

   if (str == NULL)
   {
        return (NULL);
   }
   for (; str[size] != '0'; size  )
       mp = malloc(size * sizeof(str)   1);
       /*   1 to get last part of the str */
   if (mp == 0)
   {
       return (NULL);
   }
   else
   {
       for (; i < size; i  )
       {
           mp[i] = str[i];
       }
   }
   return (mp);
}

CodePudding user response:

First, just because it compiles successfully, this does not mean that your code is correct. It just means that syntactically the compiler is fine. I hope you use the maximum warning level and correct your code until all warnings and errors are gone.

You have multiple problems:

  1. You seem to look for the terminating end-of-string marker. But instead of the correct '\0' you typed '0'. This can lead to a much too big size, depending where a zero digit is found. Depending on your system, a segmentation fault is also possible.

  2. sizeof is an operator that yields the size of its argument, in your case the size of a pointer. str is of type char *. Effectively you allocate too much, but this is harmless.

  3. The for loop uses the memory allocation as its body. I'm sure you didn't mean this, but there is no empty statement. So you are allocating multiple memory spaces, which are leaks in the end.

    An empty statement is a single semicolon or an empty pair of curly braces.

    What you most probably want to achieve is to find the number of characters that str points to. You can get it by calling strlen(str).

  4. i is not initialized, it can have any value. This can lead to a segmentation fault, if it starts with a negative value.

  5. You did not add the end-of-string marker in the duplicate. Depending on the other code we don't see, this can lead to segmentation faults.

This is a possible solution without calling strlen():

char *_strdup(const char *str)
{
    int i;
    int size;
    char *mp;

    if (str == NULL)
    {
        return NULL;
    }

    for (size = 0; str[size] != '\0'; size  )
    {
        /* just looking for the end of the string */
    }
    size  ;
    /*   1 for the end-of-string marker */

    mp = malloc(size);
    if (mp == NULL)
    {
        return NULL;
    }

    for (i = 0; i < size; i  )
    {
        mp[i] = str[i];
    }
    return mp;
}

I made a bit more:

  1. Use separate variable definitions, it avoid errors and eases maintenance.

  2. return is not a function and needs no parentheses for its expression.

  3. Put the initialization of the index variable where it belongs, in the initializing statement of for. This way everything about this index is at one place.

  4. Consider the end-of-string marker by incrementing size. This eases the following code.

  5. Since sizeof (char) is 1, it can be ommitted at the calculation of the needed memory size.

  6. Compare mp with NULL instead of 0. It is a pointer, and this is C, not C .

CodePudding user response:

Your variable i has been declared but not initialized so a random number is used in your for(; i < size; Just add int i = 0, size = 0; at the beginning or change your for statement to for(i = 0; i < size; i )

This was the reason for your segmentation fault. Some other issues: As mentioned in comments string termination character is not '0'. It's either 0 or '\0'. You are calling malloc on each iteration of your for statement. This causes memory leak.Just call it once after you got your string size right. This is fixed by putting a semicolon after the for. Maybe something like this.

char *_strdup (char *str)
{
  int i, size;
  char *mp;

  if (str == NULL)
    {
      return (NULL);
    }
  for (size = 0; str[size] != 0; size  );
  mp = malloc (size * sizeof (str)   1);
  /*   1 to get last part of the str */
  if (mp == 0)
    {
      return (NULL);
    }
  else
    {
      for (i = 0; i < size; i  )
    {
      mp[i] = str[i];
    }
    }
  return (mp);
}
  • Related