Использование memmove с указателем

Я искал по всему Stackru, но не смог найти именно то, что я пытаюсь сделать. Я хотел бы скопировать объекты-указатели в указатель COPYTO. Затем можно вызвать COPYTO-> х.

#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;
}

Эта программа компилируется, но не запускается. У него есть всплывающая поговорка: "Нарушение прав чтения" 0xabababab

Я пришел из C# и обнаружил, что C невероятно трудно понять......

1 ответ

Решение

Самая большая проблема с этой строкой:

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

COPYTO это указатель Вы распределили память с malloc и сохранил начало этой памяти COPYTO, Этот адрес является пунктом назначения, который вы хотите.

&-оператор возвращает адрес переменной, &COPYTO возвращает адрес COPYTO переменная, а не там, где она указывает.

Правильная версия:

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

Другая проблема заключается в том, как вы звоните malloc:

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

sizeof(expression) возвращает количество байтов, которые expressionнуждается в памяти. sizeof(Items) возвращает количество байтов, необходимое указателю (потому что Item указатель), а не количество байтов JustArray-объект

Правильная версия:

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

Пожалуйста, помните, что это хорошая практика, чтобы проверить возвращаемое значение malloc и друзья. Если они вернутся NULL, больше нет доступной памяти, и вы должны сделать некоторую обработку ошибок.

Также для каждого malloc должен быть free, В конце printfs, пожалуйста, сделайте:

free(Items);
free(COPYTO);

strcpy(&Items->x,d);

Вы можете переписать это так:

strcpy(Items->x, d);

Причина в том, что массив распадается на указатели при передаче их функциям и назначении их указателям. "Распад" означает, что он возвращает адрес первого элемента массива.

Для следующего массива

char line[] = "Hello World";

это эквивалентно:

char *ptr1 = &line[0];
char *ptr2 = &(line[0]);
char *ptr3 = line;
Другие вопросы по тегам