HxH HxH - 9 months ago 51
C Question

How to copy a Double Pointer char to another double pointer char?

Assume I have a function return a double pointer char with new space memory. How should I copy a double pointer char to another double pointer char? Assume I malloc a new length to double pointer char A, and a old array B.

char **newArray(char **B, int oldLen, int newLen){
char **A = malloc(newLen * sizeof(char*));
// if(A == NULL){
// perror("Failed to allocate");
// exit(1);
// }
memcpy(A, B, oldLen);//can copy memory from B to A?
return A;

Answer Source

You're missing the byte-size of the item in your sequence of items being copied. This:

memcpy(A, B, oldLen);

simply copies oldLen bytes from the address held in B to the address held in A. unless your item is one byte large (and it isn't; they're pointers) the count is undersized. Just as you did in the malloc call prior in the same code, the item size must be included in the byte-sizing calculation:

memcpy(A, B, oldLen * sizeof (char*)); 

Finally, you can use realloc to simplify this code

char **newArray(char **B, int oldLen, int newLen)
    char **A = realloc(B, newLen * sizeof(char*));sizeof(char*));
    if(A == NULL)
        // Note: B is still valid here. What you want to do with it
        //  including nothing, is up to you. Your current logic just
        //  terminates the process, so we leave it alone and just exit.
        perror("Failed to allocate");
    return A;

If the memory manager in your implementation has to expand the sequence, it will perform the all the copying for you from the old to the new buffer, and free the old buffer. But there is an added benefit: allocation filling.

Most modern dynamic memory managers have a fixed allocation page size. For example, no matter how small an allocation you request, the allocator may round up to the nearest multiple of, say 16 bytes. It remembers the sizing you requested, of course, but it also has an internal capacity. If your newly expanded space request to a realloc "fits" within the existing capacity, no actual reallocation is required. Instead, the implementation can simply updates the "used" magnitude of the current allocation to note more of the capacity is now used, and the same pointer passed in can be returned. This promotes more efficient memory management, and potentially significantly faster resizing if you're doing so in small chunks.

Just something to consider.