【问题标题】:Copy void* to a location in an array, C将 void* 复制到数组中的某个位置,C
【发布时间】:2021-08-31 14:21:51
【问题描述】:

我有这个结构:

typedef struct {
    int size;
    int capacity;
    int element_size;
    void* data;
} array;

我有一个函数可以将一个 void ptr 附加到数据中。正如您所看到的,大小每次都会增加,因此数据不会被覆盖。我正在尝试根据数组的当前大小将 data_ptr 复制到数据数组中。但是这个值是不可赋值的。我已经使用 memcpy 进行了这项工作,但我只想复制指针而不是它指向的内容。有什么建议吗?

array alloc_array(int capacity, int element_size) {
    void* data_alloc = malloc(capacity * element_size);
    return (array) {.size = 0, .capacity = capacity, .element_size = element_size, .data = data_alloc};
}

void append(array* arr, void* data_ptr) {
    arr->data + (arr->size * arr->element_size) = data_ptr;
    arr->size++;
}

【问题讨论】:

  • 我有点困惑。你是说data 指向一个实际数据数组,但你在某处埋有另一个指针?
  • 假设您的 typedef 执行它在锡上所说的那样,我不知道您为什么认为需要进行任何附加。只需将您的指针分配给data。如果你想要一个指针数组,那就是void**,而不是void*
  • but I just want to copy the pointer not what it is pointing to 要将指针 value 复制到哪里? element_size 是否至少等于 sizeof(void*)
  • 是的,当您创建数组时,您会传递正在使用的元素的大小。然后使用当前元素的数量按它们的大小,即复制 data_ptr 的位置,然后迭代大小。
  • @Jack Delahunt 您显示的代码没有意义。目前尚不清楚您要做什么。

标签: c memory-management


【解决方案1】:

我假设您要附加data_ptr 指向的对象。不是data_ptr 指针本身。

只需使用 realloc。


void append(array* arr, void* data_ptr) {
    
    if (arr->size + 1 > arr->capacity) {
       size_t new_capacity = arr->capacity + 1; // consider 1+2*arr->capacity
       void *new_data = realloc(arr->data, new_capacity * arr->element_size);
       if (!new_data)
         .. error handling ...
       // update resized arr
       arr->capacity = new_capacity;
       arr->data = new_data;
    }
    // find pointer to a new element at the end of new_data
    char *dst = (char*)arr->data + data->size * arr->element_size;
    // copy new element there
    memcpy(dst, data_ptr, arr->element_size);
    arr->size++;
}

如果你想添加指针本身,只需将上面的函数包装在帮助器中:

void append_ptr(array* arr, void* ptr) {
   append(arr, &ptr);
}

确保arr->element_size == sizeof (void*)

【讨论】:

    【解决方案2】:

    根据帖子下的 cmets 使用 void** 可以使用。这允许您使用 [] 将其尊重为 void* ,然后可以重新分配。

    【讨论】:

      【解决方案3】:

      你需要决定你想要两个选项中的哪一个。

      1. 指向数据元素的指针数组。你只复制指针。去掉element_size,就不需要了(确实,不同的元素可能有不同的大小)。将data 声明为void** data;append 应该是这样的:

         arr->data[arr->size] = data_ptr;
         arr->size++;
        
      2. 一组数据元素。您复制实际数据。保持element_size 并保持datavoid* data; append 应该是这样的:

         memcpy((char*)arr->data + arr->size * arr->element_size,
                data_ptr, 
                arr->element_size);
         arr->size++;
        

      在任何情况下,您都应该在访问arr->data 之前检查capacity 并根据需要重新分配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-20
        • 2012-01-01
        • 2023-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多