Reputation: 1491
I want to concatenate two strings using a function that returns the resulting string. it would be something like this:
char *String_Concat (char *String_1, char *String_2)
{
char *StringResult;
//memmove String_1 to StringResult
//memmove String_2 to StringResult
return StringResult;
}
I wonder if that is a good way of doing that, since I know little about memory management. StringResult does not have a defined length, and I am not sure what will happen after two memmove operations.
I suppose StringResult will be cleaned up by the function itself, since I do not use malloc(), correct?
Upvotes: 1
Views: 1695
Reputation: 70941
For completeness, assuming using memmove()
was just an idea, not a requirement, strcpy() and strcat() are functions of choice here, as they are specially crafted to work on C-"strings", that is 0
-terminated char
-arrays.
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for strcpy() and strcat() */
#include <errno.h> /* for errno and EINVAL */
char * stralloc_and_cat(const char * s1, const char * s2)
{
char * s = NULL;
if ((NULL == s1) || (NULL == s2))
{
errno = EINVAL;
}
else
{
if (NULL != (s = malloc(strlen(s1) + strlen(s2) + 1)))
{
strcpy(s, s1);
strcat(s, s2);
}
}
return s;
}
And call it like this:
#include <stdlib.h>
#include <stdio.h>
char * stralloc_and_cat(const char * s1, const char * s2);
int main(void)
{
char * s1 = "hello ";
char * s2 = "world";
char s = stralloc_and_cat(s1, s2);
if (NULL == s)
{
perror("stralloc_and_cat() failed");
}
else
{
printf("%s\n", s);
free(s);
}
return 0;
}
Upvotes: 0
Reputation:
char *String_Concat (char *String_1, char *String_2)
{
size_t len1 = strlen(String_1);
size_t len2 = strlen(String_2);
char *StringResult = malloc(len1+len2+1);
//might want to check for malloc-error...
memcpy(StringResult, String_1, len1);
memcpy(&StringResult[len1], String_2, len2+1);
return StringResult;
}
So, C has the concept of storage
for objects. The storage of an object determines its lifetime, as C is not garbage-collected. If you want to create a new string, You must reserve storage for it. The easiest way would be automatic storage, but that is associated with the scope of the function it is declared in, so automatic variables cease to exist after function return. Alternatively, you could use static storage, but that cannot be of variable size, and multiple calls to the function would use the same storage. Finally, you can use allocated storage, which requires malloc()/calloc()/realloc()/free()
.
See C11 draft standard, section 6.2.4 Storage durations of objects
Upvotes: 4
Reputation: 42964
You have to use malloc()
to dynamically allocate some memory for the resulting concat string.
And in this case the caller is responsible to invoke free()
to release the memory pointed by the returned string pointer.
An alternative would be to design a function expecting a pointer to a caller-allocated destination buffer, large enough to store the total resulting string.
Following the first option, you can consider code like this (live on Ideone):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Concatenates string1 and string2.
// Returns the concatenated (string1+string2), or NULL on errors.
// NOTE: Memory for the returned string is allocated with malloc()
// by the function, so the caller is responsible to release it with
// a call to free().
char *StringConcat(const char *string1, const char *string2)
{
char *stringResult;
size_t len1;
size_t len2;
// Check for NULL pointers...
// (Return NULL, or whatever your design is...)
if (string1 == NULL || string2 == NULL) {
return NULL;
}
len1 = strlen(string1);
len2 = strlen(string2);
// +1 for terminating NUL ('\0')
stringResult = malloc(len1 + len2 + 1);
if (stringResult == NULL) {
return NULL; // Allocation error
}
// Copy characters from first string
// (exclduing the terminating NUL --> len1)
memcpy(stringResult, string1, len1);
// Copy characters from second string
// (including the terminating NUL --> len2+1)
memcpy(stringResult + len1, string2, len2+1);
// Return destination string pointer to the caller.
// NOTE: Memory must be freed by the caller calling free().
return stringResult;
}
// *** TEST ***
int main(void)
{
// Test the function
char * str = StringConcat("Hello ", "World");
// Print the resulting string
printf("%s\n", str);
// Don't forget to free() memory allocatd by the concat function
free(str);
// All right
return 0;
}
Upvotes: 0
Reputation: 1270
Here's how I would handle it, using existing string commands instead of memcpy. I'm assuming you want something like strcat that doesn't affect the source strings.
char* string_concat(char *dest, const char* string1, const char* string2)
{
strcpy(dest, string1);
strcat(dest, string2);
return dest;
}
To use it, you need to pass in a pointer to the buffer you want the result stored in. You can use malloc to make it the size you need. Free it when you're done.
char *str1 = "abc";
char *str2 = "def";
size_t len = strlen(str1) + strlen(str2);
char *newstr = malloc(len + 1);
string_concat(newstr, str1, str2);
printf("%s\n", newstr);
free(newstr);
There is simply no way to deal with arbitrary-length strings without allocating memory, so you'll be stuck with malloc/free unless you're using character arrays with fixed lengths. If you want to abstract the logic of deciding how big of a buffer to allocate you can do something like this:
size_t string_concat(char* dest, char* string1, char* string2)
{
if(!dest)
{
return strlen(string1) + strlen(string2) + 1;
}
strcpy(dest, string1);
strcat(dest, string2);
return 0;
}
Then you can ask it how much to allocate like this:
char* newstr = malloc(string_concat(0, str1, str2));
But you lose the syntactical convenience of it returning a pointer to dest.
Upvotes: 2
Reputation: 53006
If you want to avoid dynamic allocation you can do something like
int main( int argc, char **argv)
{
char String_1[8] = "Exa";
/* ^ enough space for Example\0 */
const char *String_2 = "mple";
printf("%s\n", strcat(String_1, String_2));
return 0;
}
Upvotes: 0
Reputation: 399863
It's a very bad idea, and no "cleaning" will magically happen by the function.
You cannot do this, it's not a valid way to implement string concatenation in C.
You must make sure there's enough writable memory before doing anything, so in general you must call malloc()
.
Upvotes: 0