Jérémy Pouyet
Jérémy Pouyet

Reputation: 2019

C language : string concatenation on string pointer

I have code this add_str function :

void    add_str(char *str1, char *str2, char **res)
{
  int   i;
  int   j = 0;

  res[0] = malloc((strlen(str1) + strlen(str2) + 1) * sizeof(char));
  if (res[0] == NULL)
    return;
  for (i = 0; str1[i]; i++)
    res[0][j++] = str1[i];
  for (i = 0; str2[i]; i++)
    res[0][j++] = str2[i];
  res[0][j] = '\0';
}

It receives 2 strings, str1 and str2 and a pointer an string **res which is not malloc. My function add str1 and str2 on **res.

My question is : Is there a way to do not write res[0] each time I have to do something with it ?

Upvotes: 4

Views: 253

Answers (5)

I would use another pointer variable to hold the result string, which avoids dereferencing the result variable all the time. Apart from that, of course, you should avoid using the array subscript operator where a simple pointer dereference is what you do. I have also made a few other changes to your example code to make it more concise, feel free to ignore them.

void add_str(char *str1, char *str2, char **res) {
    char* result = *res = malloc((strlen(str1) + strlen(str2) + 1) * sizeof(char));
    //Dereferencing a NULL pointer will safely crash your program on any sane system.
    //if (!result) return;
    int   j = 0;    //Since C99 you are allowed to mix code and variable declarations.
    for(int i = 0; str1[i]; i++) result[j++] = str1[i];
    for(int i = 0; str2[i]; i++) result[j++] = str2[i];
    result[j] = '\0';
}

If pointers are used to their full potential, your code can look like this:

void add_str(char *str1, char *str2, char **res) {
    char* result = *res = malloc((strlen(str1) + strlen(str2) + 1) * sizeof(char));
    while(*str1) *result++ = *str1++;
    while(*str2) *result++ = *str2++;
    *result = '\0';
}

Upvotes: 0

Devolus
Devolus

Reputation: 22084

Why do you need to pass a pointer pointer anyway? You could just as well change it to this:

char *add_str(char *str1, char *str2)
{
    char *res = malloc((strlen(str1) + strlen(str2) + 1));
    if (res == NULL)
        return NULL;

    char *ret = res;

    while(*str1 != 0)
        *res++ = *str1++;

    while(*str2 != 0)
        *res++ = *str2++;

    *res = '\0';
    return ret;
}

It has the same effect and you don't have to deal wit that ugly construct.

Upvotes: 2

barak manos
barak manos

Reputation: 30136

This is not a direct answer to your question, but more of a general coding advice:

In order to properly manage all dynamic memory operations within your program, you should strive (try as much as you can) to have both operations x=malloc(...) and free(x) executed from the same function.

In most cases, if you design your code correctly, then you can achieve this.

In some cases, when the flow is asynchronous, it is impossible to do so. For example, one function allocates the buffer, and after some event occurs in the system, another function (AKA callback) releases the buffer.

In such cases, you should still try to have both operations within the same "scope" (class, file or module).

In your coding example, function add_str allocates the buffer but does not release it, which means some other function will eventually have to do it (or you will have memory leaks). Hence, if possible, then you should try to perform the malloc outside of this function.

Upvotes: 2

Peter Bloomfield
Peter Bloomfield

Reputation: 5766

res is a pointer to a pointer, so you need to dereference it before you use it. You're right that res[0] isn't the right way to do that though in this context. Use (*res) instead.

Upvotes: 6

EricSchaefer
EricSchaefer

Reputation: 26340

What you really want is to dereference:

*res

Upvotes: 3

Related Questions