felipX
felipX

Reputation: 21

Unexpected segmentation fault when trying to mix some string

I need to manipulate an string in this way:

If the character is '+' or '-' or '/' or '*', move them to the end of buffer, if not, move to the beginning of the buffer.

My solution is quite simple:

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

void mix_the_string(char ** buff, char ** string)
{
    printf("The string which will be printed is : %s\n",*string);

    int i = 0;
    int j = strlen(*string) - 1;

    while(i< strlen(*string))
    {
        if(*string[i] != '+' || *string[i] != '-' || *string[i] != '*' || *string[i] != '/')
        {

            printf("in the first if, i = %d, *string[i] = '%d'\n",i,(int)*string[i]);

            *buff[i] = *string[i];
        }
        else
        {
            printf("in the second if, i = %d, *string[i] = '%d'\n",i,(int)*string[i]);
            *buff[j] = *string[i];
        }

        i++;
        j--;
    }
}

int main()
{    
    char * buff  = (char *) malloc(50);
    char * string  = (char *) malloc(50);

    string = "1+2+3";

    mix_the_string(&buff,&string);
    puts(buff);
    free(buff);
    free(string);

    return 0;
}

The output of this code is:

 The string which will be printed is : 1+2+3
 in the first if, i = 0, *string[i] = '49'
 in the first if, i = 1, *string[i] = '49'
 Segmentation fault

I expected with this example that output would be like:

The string which will be printed is : 1+2+3
in the first if, i = 0, *string[i] = '49'
in the second if, i = 1, *string[i] = '43'
in the first if, i = 2, *string[i] = '50'
in the second if, i = 3, *string[i] = '43'
in the first if, i = 4, *string[i] = '51'
123++

Where am I going wrong?

Upvotes: 0

Views: 89

Answers (2)

Achal
Achal

Reputation: 11921

There are lot of bugs in your code.

  • first string = "1+2+3"; and then doing free(string) is not correct. First copy it using strcpy(string,"1+2+3"); and then free(string)
  • string is double pointer in mix_the_string(). Accessing like *string[i] is not correct because string is not array of pointer. instead of this use *(*string+i). Same applicable for buf also.
  • finally casting of malloc is not required. just char * buff = malloc(50); is fine.
  • And moreover you don't need to pass &string to mix_the_string(). just pass string thats enough.

Here is the expected code which you want

void mix_the_string(char ** buff, char ** string)
{
    printf("The string which will be printed is : %s\n", *string);

    int i = 0;
    int j = strlen(string[0]) - 1;

    while (i < strlen(string[0]))
    {
        if (*(*string + i) != '+' || *(*string + i) != '-' || *(*string + i) != '*' || *(*string + i) != '/')
        {
            printf("in the first if, i = %d, *string[i] = '%d'\n", i, *(*string + i));

            *(*buff + i) = *(*string + i);
        }
        else
        {
            printf("in the second if, i = %d, *string[i] = '%d'\n", i, *(*string + i));
            *(*buff + j) = *(*string + i);
        }
        i++;
        j--;
    }
}

int main()
{
    char * buff = (char *)malloc(50);
    char * string = (char *)malloc(50);

    strcpy(string, "1+2+3");

    mix_the_string(&buff, &string);
    puts(buff);
    free(buff);
    free(string);

    return 0;
}

Upvotes: 0

rafix07
rafix07

Reputation: 20936

There is difference between *string[i] and (*string)[i] notation. [] has higher precedence than * operator. You pass string by pointer to pointer, so you should call (*string)[i] in every line of your code.

(*string)[i] means - dereference pointer to array and get i-th element of string array

now you are doing

*string[i] - get i-th element of string array (!! but this is not array, this is only one element) and dereference first element

Do the same with buff.

And in main function you should copy 1+2+3 string literal into string buffer for example by strcpy function.

Upvotes: 5

Related Questions