Home > Back-end >  How to copy with memcpy?
How to copy with memcpy?

Time:05-03

char *concat(char *num1, const char *num2, int index) {

    int length1 = strlen(num1);
    int length2 = strlen(num2); 
    int lengthNum = 0;                   
    char *num = malloc(length1   length2   1);

    if (num == NULL) {
        free(num);
        return NULL;
    }
    // memcpy(num, num1, length1);
    // memcpy(num   length1, num   index, length2   1);    

    for (int i = 0; i < length1; i  ) {
        num[lengthNum] = num1[i];
        lengthNum  ;
    }
    for (int i = index; i < length2; i  ) {
        num[lengthNum] = num2[i];
        lengthNum  ;
    }
    return num;
}

I tried to use memcpy, but than my program doesn't work correctly (copies wrongly, but valgrind doesn't show an error).

But when I use two for loops instead, it works properly, but than valgrind shows an error

uninitialised value was created by a heap allocation.

How to use properly memcpy in this case?

CodePudding user response:

memcpy(num, num1, length1);
memcpy(num   length1, num2, length2   1); 

CodePudding user response:

Your program has multiple issues:

  • freeing a null pointer when malloc failed is useless (but harmless).
  • you allocate length1 length2 1 bytes, which is most likely too large as you intend to copy from index in the second string.
  • you should use type size_t for the lengths and offsets.
  • you copy from num2 index without checking that index is a valid offset inside the string num2.
  • you should set a null terminator at the end of the new string.

Here is a modified version:

#include <stdlib.h>
#include <string.h>

char *concat(const char *num1, const char *num2, size_t index) {
    size_t length1 = strlen(num1);

    /* skip index bytes in num2 */
    while (index --> 0 && *num2)
        num2  ;

    size_t length2 = strlen(num2);
    char *num = malloc(length1   length2   1);

    if (num != NULL) {
        size_t j = 0;

        while (*num1) {
            num[j  ] = *num1  ;
        }
        while (*num2) {
            num[j  ] = *num2  ;
        }
        num[j] = '\0';
    }
    return num;
}

and using memcpy:

#include <stdlib.h>
#include <string.h>

char *concat(const char *num1, const char *num2, size_t index) {
    size_t length1 = strlen(num1);
    /* skip index bytes in num2 */
    while (index --> 0 && *num2)
        num2  ;
    size_t length2 = strlen(num2);
    char *num = malloc(length1   length2   1);
    if (num != NULL) {
        memcpy(num, num1, length1);
        memcpy(num   length1, num2, length2   1);    
    }
    return num;
}

concat returns a pointer to an allocation array. It is the responsibilty of the caller to free this object after use. For example:

#include <stdio.h>

int main() {
    char *p = concat("Hello", "dear world", 4);
    if (p != NULL) {
        printf("%s\n", p);
        free(p);
    }
    return 0;
}
  • Related