如何解决将内存地址复制到内存块
我已经很长时间没有使用C编程了,最近决定重新使用它。我发布此问题是因为对于memcpy
函数,我有些不了解。我希望能够将内存地址复制到一块内存中。例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char name[255];
char last_name[255];
short age;
};
int main(void) {
struct Person* person = calloc(1,sizeof(struct Person));
strcpy(person->name,"John");
strcpy(person->last_name,"Travolta");
person->age = 66;
void* buffer = calloc(1,sizeof(struct Person*));
// This won't copy the address of `person` into buffer.
// I don't understand why.
memcpy(buffer,&person,sizeof(struct Person*));
// If I want to allocate and copy the contents where `person`
// is pointing to that works absolutely fine:
//
// void* buffer = calloc(1,sizeof(struct Person));
// memcpy(buffer,person,sizeof(struct Person));
//
// But that's not what I want. I don't want a copy of the data.
// I want a copy of `person`,NOT a copy of the data where `person`
// is pointing to.
struct Person* ptr = (struct Person*) buffer;
printf("person address: %p\tptr address: %p.\n",ptr);
return 0;
}
我已经用gcc -Wall test-ptr.c -o test-ptr
对其进行了编译。运行该程序时,我期望printf
给我完全相同的地址。但是,这就是我得到的:
person address: 0x800a40000 ptr address: 0x800644008.
现在为上述问题提供一些背景知识。为什么要将一个内存地址复制到一个内存块中?出于学习目的,我完全从头开始实现动态数组数据结构。其界面是:
struct DynamicArray new_dynamic_array(size_t element_size);
void* da_get_nth(struct DynamicArray* da,size_t i);
void da_append(struct DynamicArray* da,void* element);
void da_insert(struct DynamicArray* da,void* element,size_t i);
void* da_delete(struct DynamicArray* da,size_t i);
如果我请求一个内存块(使用calloc
或malloc
),然后用我想在动态数组中存储这些内存块地址的数据填充它,而不用动态数组来保存此类数据的副本。
总结一下:我定义的动态数组操作是使用memcpy
实现的,目前还没有达到预期的效果(尽管复制数据按预期进行)。我希望能够有效地将动态数组任何保留在任意数据类型中(数据的副本或内存地址的副本,具体取决于动态数组操作的方式)称为:如果我传递了一个指针,则复制数据,但如果传递一个指针的地址,则应复制其内存地址。)
我找到了以下答案:Store pointer address in malloced memory似乎是此问题的答案。但是,我并不完全了解它,这也意味着我的动态数组实现将需要区分何时使用memcpy
或何时直接分配值。是否可以使用memcpy
以外的其他功能解决此问题?还是我完全缺少或不了解的其他东西?我在示例中的推理出了什么问题?
抱歉,文章的长度太长了,谢谢!!
解决方法
printf("person address: %p\tptr address: %p.\n",person,ptr);
此处,ptr
与buffer
相同。它是指向指针的指针,而不是存储在buffer
中的指针。
它来自以下声明:
struct Person* ptr = (struct Person*) buffer;
很明显,ptr
与buffer
的指针相同,只是类型不同。
您想要的是:
// The cast is not required in C,but I'm keeping it
struct Person **pptr = (struct Person **) buffer;
现在pptr
是指向Person
的指针,这正是我们想要的。
我们可以评估*pptr
:
printf("person address: %p\tpptr address: %p.\n",(void *) person,(void *) *pptr);
请注意,强制转换必须严格符合ISO C要求; %p
转换说明符需要一个void *
类型的参数,而不仅仅是任何指针。
如果我们只使用memcpy
,就不需要pptr
;我们可以使用以下方式存储值:
*pptr = person; // instead of memcpy(&pptr,&person,sizeof pptr);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。