简体   繁体   中英

strcpy giving segmentation fault

Consider the following code:

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

char *cexpGen();
char *chartoStr(char c);

char c_exp[] = "1";
char expressions[2] = {'+', '-'};

int main()
{
    cexpGen();
    printf("%s", c_exp);
    return 0;
}

char *cexpGen()
{
    int now = 1;
    while ((c_exp[strlen(c_exp) - 1]) > 10)
    {
        if ((c_exp[strlen(c_exp) - 1]) == '+' || (c_exp[strlen(c_exp) - 1]) == '-')
        {
            strcpy(c_exp, chartoStr(((c_exp[strlen(c_exp) - 2]) + 1)));
            continue;
        }

        if (now = 1)
        {
            strcpy(c_exp, chartoStr(expressions[0]));
            now++;
            cexpGen();
        }

        if (now = 2)
        {
            strcpy(c_exp, chartoStr(expressions[1]));
            now++;
            cexpGen();
        }

        if (now = 3)
        {
            strcpy(c_exp, chartoStr(((c_exp[strlen(c_exp) - 1]) + 1)));
        }
    }
}

char *chartoStr(char c)
{
    char s[2] = {c, '\0'};
    return s;
}

I wanted to concatenate a cahracter and an string, But we don't have the function to do that, So I've defined a function chartoStr. Also c_exp and expressions varaibles aren't in read only mode, But strcpy() gives me segmentation fault. I also tried other functions any way, Like strcat, Which didn't help.

In case it helps, I debug it in VS Code. It opens strcpy-sse2-unaligned.S and shows segmentation fault in one of it's lines.

Is launch.json or task.json files needed? I don't think they may help, So I don't full the question with codes, But tell me if they're needed.

chartoStr() returns a local that is no longer available at function's end as well answered by @kiran Biradar

char s[2] = {c, '\0'};
return s;  // bad, UB

An alternative to calling chartoStr() it to create the string in the calling code using a compound literal (Since C99).

// strcpy(c_exp, chartoStr(expressions[0]));
//            v-----------------------------v---- compound literal         
strcpy(c_exp, (char []){expressions[0], '\0'});

A nice attribute is that there is no expensive allocation nor pointer to free. The compound literal is valid until the end of the block.


Note that code could employ other improvements by saving the length size_t len = strlen(c_exp) once early in cexpGen() and using it to append.

// strcpy(c_exp, chartoStr(expressions[0]));
c_exp[len++] = expressions[0];
c_exp[len] = '\0';

Other Problems

Take heed to @alk about char c_exp[] = "1";

while (c_exp[strlen(c_exp) - 1]) > 10 is undefined behavior should strlen(c_exp) return 0. Perhaps while ((len = strlen(c_exp)) > 0 && c_exp[len - 1]) > 10 ?

if (now = 1) is always true. @user3386109

You are getting segfault because you are returning address of local variable.

char s[2] = {c, '\0'};
    return s;

s will be destroyed once control exits chartoStr function.

Compiler is also warning the same

warning: function returns address of local variable [-Wreturn-local-addr]

  return s; ^ 

You don't need strcpy to copy the single character you can directly assign.

To solve your problem you can try as below.

char *chartoStr(char c)
{
    char *s = malloc(2);
     s[0] = c;
     s[1] =  '\0';
    return s;
}

Don't forget to free s after work done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM