微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将内存地址复制到内存块

如何解决将内存地址复制到内存块

我已经很长时间没有使用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);

如果我请求一个内存块(使用callocmalloc),然后用我想在动态数组中存储这些内存块地址的数据填充它,而不用动态数组来保存此类数据的副本。

总结一下:我定义的动态数组操作是使用memcpy实现的,目前还没有达到预期的效果(尽管复制数据按预期进行)。我希望能够有效地将动态数组任何保留在任意数据类型中(数据的副本或内存地址的副本,具体取决于动态数组操作的方式)称为:如果我传递了一个指针,则复制数据,但如果传递一个指针的地址,则应复制其内存地址。)

我找到了以下答案:Store pointer address in malloced memory似乎是此问题的答案。但是,我并不完全了解它,这也意味着我的动态数组实现将需要区分何时使用memcpy或何时直接分配值。是否可以使用memcpy以外的其他功能解决此问题?还是我完全缺少或不了解的其他东西?我在示例中的推理出了什么问题?

抱歉,文章的长度太长了,谢谢!!

解决方法

printf("person address: %p\tptr address: %p.\n",person,ptr);

此处,ptrbuffer相同。它是指向指针的指针,而不是存储在buffer中的指针。

它来自以下声明:

struct Person* ptr = (struct Person*) buffer;

很明显,ptrbuffer的指针相同,只是类型不同。

您想要的是:

// 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 举报,一经查实,本站将立刻删除。