I was running this simple program, the output i get is a "bus error". using some debugging statements i found the point at which it occurs was at the strcat() call.
#include<stdio.h>
#include<string.h>
main()
{
char *s = "this is ";
char *s1 = "me";
strcat(s,s1);
printf("%s",s);
return 0;
}
I run it using a gcc compiler on a MAC, 64-bit OS. Please let me know if i need to provide any more specification.
Thanks!
A little background:
The expressions "this is "
and "me"
are string literals; they are 9- and 3-element arrays of char
(const char
in C++) respectively with static extent (meaning the memory for them is allocated at program startup and held until the program exits). That memory may or may not be writable, depending on the platform, so attempting to modify a string literal results in undefined behavior (meaning the compiler can literally do anything it wants to). In short, you cannot write to a string literal.
When you write strcat(s, s1);
, you're running into two problems: first, the target array is a string literal, which as I mentioned above is not writable. Secondly, it's not large enough to hold the additional characters; it's sized to hold 9 characters (including the 0 terminator), but you're attempting to store 11 characters to it. This is a buffer overflow, which can lead to Bad Things if you clobber something important.
You'll have to allocate a target buffer that is writable. You have several choices:
You can declare an array that's big enough to hold the resulting string, although in general you're not going to know how big "big enough" is at compile time:
char *s = "this is ";
char *s1 = "me";
char target[11];
strcpy(target, s);
strcat(target, s1);
// alternately, sprintf(target, "%s%s", s, s1);
In C99, you can declare a variable-length array (VLA) whose size isn't known until runtime:
char *s = "this is ";
char *s1 = "me";
char target[strlen(s) + strlen(s1) + 1];
strcpy(target, s);
strcat(target, s1);
// alternately, sprintf(target, "%s%s", s, s1);
You can dynamically allocate a target buffer using malloc
or calloc
(this is actually the preferred method, since the buffer can be resized as necessary, unlike a VLA):
char *s = "this is ";
char *s1 = "me";
char *target = malloc(strlen(s) + strlen(s1) + 1);
strcpy(target, s);
strcat(target, s1);
// or sprintf(target, "%s%s", s, s1);
...
free(target); // when you're finished with the buffer
"this is "
and "me"
are string literals which may reside in a read-only part of your address space. You should not attempt to modify these.
char s[] = "this is ";
char s1[] = "me";
This will ensure the literals are copied to stack - which is writable. Then your following strcat will overflow the stack buffers, which is just as bad.
The below will work - even though using strcat
and not strncat
is in general bad practice.
#include <stdio.h>
#include <string.h>
int main()
{
char s[100] = "this is ";
char *s1 = "me";
strcat(s,s1);
printf("%s",s);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With