Reputation: 1964
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.
Upvotes: 1
Views: 413
Reputation: 153517
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
Upvotes: 3
Reputation: 12732
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.
Upvotes: 1