Использование 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(©TO, 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(©TO, Items, sizeof(JustArray));
COPYTO
это указатель Вы распределили память с malloc
и сохранил начало этой памяти COPYTO
, Этот адрес является пунктом назначения, который вы хотите.
&
-оператор возвращает адрес переменной, ©TO
возвращает адрес 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
, В конце printf
s, пожалуйста, сделайте:
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;