Search code examples
cpointersstructmemmove

Using memmove with pointer


I searched all over StackOverflow but could not find exactly what I am trying to do. I'd like to copy pointer Items over to pointer COPYTO. Then able to call COPYTO->x.

#include <stdio.h>

typedef struct JustArray {
    char x[30];
  } JustArray;

int main()
{
    JustArray *Items, *COPYTO;
    char d[10] = "Test";
    Items = malloc(sizeof(Items));
    COPYTO = malloc(sizeof(COPYTO));
    strcpy(&Items->x,d);
    memmove(&COPYTO, Items, sizeof(JustArray));

    printf("Pointer: %p\n", &d);
    printf("Address: %u\n",&d);
    printf("Value: %s\n", Items->x);
    printf("Value: %s\n", COPYTO->x);

    return 0;
}

This program compiles but will not run. It have a popup saying: Access violation reading location 0xabababab.

I came from C# and finding C to be incredibly difficult to understand......


Solution

  • The biggest problem is with this line:

    memmove(&COPYTO, Items, sizeof(JustArray));
    

    COPYTO is a pointer. You allocated memory with malloc and saved the start of this memory to COPYTO. This address is the destination you want.

    The &-operator returns the address of a variable, &COPYTO returns the address of the COPYTO variable, not where it is pointing.

    Correct version:

    memmove(COPYTO, Items, sizeof(JustArray));
    

    Another problem is the way you call malloc:

    Items = malloc(sizeof(Items));
    COPYTO = malloc(sizeof(COPYTO));
    

    sizeof(expression) returns the number of bytes that expression needs in memory. sizeof(Items) returns the number of bytes that a pointer needs (because Item is a pointer), not the numbers of bytes a JustArray-object needs.

    Correct version:

    Items = malloc(sizeof *Items);
    COPYTO = malloc(sizeof *COPYTO);
    

    Please remember it's a good practice to check for the return value of malloc & friends. If they return NULL, there is no more memory available and you should do some error handling.

    Also, for every malloc there must be a free. At the end of the printfs, please do:

    free(Items);
    free(COPYTO);
    

    strcpy(&Items->x,d);
    

    You can rewrite this like this:

    strcpy(Items->x, d);
    

    The reason is that array decay into pointers when passing them to functions and assigning them to pointers. "Decay" means that it returns the address of the first element of the array.

    For the following array

    char line[] = "Hello World";
    

    these are equivalent:

    char *ptr1 = &line[0];
    char *ptr2 = &(line[0]);
    char *ptr3 = line;