Febin Sunny
Febin Sunny

Reputation: 311

What is causing this segmentation fault in string concatenation?

I am doing an exercise in C to brush myself up on the topic. I am trying to use my program to manipulate header files; but the program returns "Segmentation fault". I have isolated the issue to the following segment of code. Can any one help me see what exactly is wrong with it ?

    header=strtok(st,"\"");
    header=strtok(NULL,"\"");
    f=fopen(header,"r");
    if(f)
    {
            while((ch=fgetc(f))!=EOF)
            fputc(ch,f2);

            fclose(f);
    }
    else
    {
            header2=(char *)malloc(strlen("/usr/include")+strlen(header));
            header2=strcat("/usr/include/",header);
            f=fopen(header2,"r");

            printf("%s\n",header2);

            while((ch=fgetc(f))!=EOF)
            fputc(ch,f2);

            fclose(f);
   }

I have noted that the issue occurs only when I am trying to access the /usr/include/ location. Some sort of authentication issue ? If so, how to over come it ? Thanks in advance. :)

Upvotes: 1

Views: 103

Answers (2)

Sourav Ghosh
Sourav Ghosh

Reputation: 134326

The major problem is in

header2=strcat("/usr/include/",header);

as you're supplying a string literal as the destination. This does not have any space to hold the concatenated string. So, you're essentially trying to access invalid memory which invokes undefined behavior.

That said, for strcat(), the behavior is, (emphasis mine)

The strcat() function appends the src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, [...]

which, in your case, involves an attempt to modify a string literal, which again, invokes UB.

Then, there are more to point out, like

Upvotes: 2

Barmar
Barmar

Reputation: 780974

You can't use a string literal as the target of strcat -- string literals are not modifiable, and it doesn't have enough space to hold the concatenated string. A better way to combine the variable with a prefix is with sprintf.

header2 = malloc(strlen("/usr/include/")+strlen(header)+1);
sprintf(header2, "/usr/include/%s", header);

Note that you need to add 1 to the combined lengths when calling malloc(), to allow space for the trailing null byte.

You could also use strcpy followed by strcat:

strcpy(header2, "/usr/include/");
strcat(header2, header);

Upvotes: 3

Related Questions