14

Using GDB, I find I get a segmentation fault when I attempt this operation:

strcat(string,&currentChar);

Given that string is initialized as

char * string = "";

and currentChar is

char currentChar = 'B';

Why does this result in a segmentation fault?

If strcat can't be used for this, how else can I concat a char onto a string?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Blackbinary
  • 3,936
  • 18
  • 49
  • 62
  • 5
    strcat requires null-terminated strings. Your single char has no null, so strcat will keep copying until it finds a null somewhere down the line, which could be on the 2nd byte by accident, or a few gigabytes down the road, all the while copying all that garbage into your string, stomping on the stack – Marc B Jan 29 '11 at 02:52

7 Answers7

17

As responded by others, &currentChar is a pointer to char or char*, but a string in C is char[] or const char*.

One way to use strcat to concatenate a char to string is creating a minimum string and use it to transform a char into string.

Example:

Making a simple string, with only 1 character and the suffix '\0';

char cToStr[2];
cToStr[1] = '\0';

Applying to your question:

char * string = "";
char currentChar = 'B';

cToStr will assume the string "B":

cToStr[0] = currentChar;

And strcat will work!

strcat ( string, cToStr );
gallo
  • 546
  • 7
  • 10
10

Because &currentChar is not a string, it doesn't finish with \0 character. You should define B as char *currentChar = 'B';. Also according to http://www.cplusplus.com/reference/clibrary/cstring/strcat string should have enough space to hold the result string (2 bytes in this case), but it is only 1 byte.

Or if you want to use char then you can do something like (depending of your code):

char string[256];
...

char currentChar = 'B';
size_t cur_len = strlen(string);
if(cur_len < 254) {
    string[cur_len] = currentChar;
    string[cur_len+1] = '\0';
}
else
    printf("Not enough space");
Elalfer
  • 5,312
  • 20
  • 25
3

I think the simplest method (not efficient) would be sprintf

sprintf(str, "%s%c", str, chr);

Nandakumar Edamana
  • 770
  • 1
  • 4
  • 10
2

strcat() takes two '\0'-terminated strings. When you pass the address of a character, the routine will look at the memory that follows the character, looking for the terminator.

Since you don't know what that memory even refers to, you should expect problems when your code accesses it.

In addition to that, your string argument does not have room to have any characters appended to it. Where is that memory written to? It will attempt to write past the end of the memory associated with this string.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
0

Both of the strings must be null-terminated. A single char isn't null terminated, so it's undefined when strcat will stop concatenating characters to the end. Also, string must contain at least enough space for both the original string and resultant string.

This works:

char string[10] = "";
char* currentChar = "B";
strcat(string, currentChar);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
helloworld922
  • 10,801
  • 5
  • 48
  • 85
  • This does not work because there is not enough space in string. To see my point, try it: http://ideone.com/0jjST – Foo Bah Jan 29 '11 at 02:54
  • There's two problems with the code. The first argument doesn't have enough space, the second one has no terminator. Why are you focused on only one issue? – Jonathan Wood Jan 29 '11 at 02:58
  • it's part of the reason, though you're right it's not the main one. fixed to include the main cause of the segfault – helloworld922 Jan 29 '11 at 02:58
0

We know that currentChar = 'B'.

This can be done

strcat(string, "B\0");

If we know currentChar will be hardcoded as 'B', this would be a good approach.
It also removes the need for char currentChar = 'B';

-1

The first argument of strcat must have enough space to hold the rest of the string. "" is a constant string and as such GCC does not allocate space.

Make it an array with enough space:

char buf[1024];

strcat(buf, "");
strcat(buf, "B");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Foo Bah
  • 25,660
  • 5
  • 55
  • 79