简体   繁体   English

设计队列的调整大小功能

[英]Designing a resize function for a queue

I'm currently trying to design a public API for a queue data structure and resize function to change its size. 我目前正在尝试为队列数据结构设计一个公共API,并调整大小函数以更改其大小。 My first intention was to do it in the following way: 我的初衷是通过以下方式做到这一点:

typedef struct queue queue;

/**
 * Resizes a given queue.
 *
 * Changes the size of the queue passed as a parameter. 
 * The content of the resized queue prior to the lesser
 * of new and old sizes is left unchanged. 
 *
 * Returns:
 *  0 - on success
 * -1 - on error and the content of the original queue is left unchanged
 */
int queue_resize(queue * queue_ptr, size_t new_size);

The problem is I read the contract to realloc and it was the following: 问题是我读了合同, realloc ,它是以下几点:

The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated. realloc函数返回指向新对象的指针(该值可能与指向旧对象的指针的值相同),如果无法分配新对象,则返回空指针。

Is it a common approach for reallocation functions to return a new object and reclaim the old one? 重新分配函数返回新对象并回收旧对象是一种常见的方法吗? So in such a case I should have redesigned the int queue_resize(queue *queue_ptr, size_t); 因此,在这种情况下,我应该重新设计int queue_resize(queue *queue_ptr, size_t); to make queue * queue_resize(queue *queue_ptr, size_t); 使queue * queue_resize(queue *queue_ptr, size_t); with the corresponding contract changes. 与相应的合同更改。

realloc must be able to move the allocated space to a different address for it to be able to work. realloc必须能够分配的空间移动到不同的地址,它是能够工作。 Imagine the memory directly after the currently allocated memory was already in use. 想象一下在当前分配的内存已在使用之后的内存。 Without relocation you could not create a contiguous sequence. 没有重定位,您将无法创建连续序列。

Typically your queue will look something like this 通常,您的队列看起来像这样

typedef struct queue {
  some_type* data_member;
  size_t size;
  size_t capacity;
  // .. perhaps more
} queue;

So when you have a queue_resize function you can just pass a queue* and the new size. 因此,当您拥有queue_resize函数时,您只需传递queue*和新的大小即可。 What you pass to realloc is not the queue* but its data_member . 您传递给realloc的不是queue*而是其data_member Since you already have a pointer to the queue object, you can just update the pointer of data_member if realloc chooses to change it. 由于您已经有一个指向queue对象的指针, data_member只要realloc选择更改它,就可以更新data_member的指针。

In this case returning a new queue* object is not necessary, because the memory footprint of queue never changes. 在这种情况下,无需返回新的queue*对象,因为queue的内存占用量不会改变。 Nor do you have to pass a queue** or anything of the sort. 您也不必传递queue**或类似的东西。

Previous answers/comments do not address what to do with the data. 先前的答案/评论未解决如何处理数据。 Consider what is done in Java when the Java run-time discovers that the Array needs to be bigger. 考虑当Java运行时发现Array需要更大时,用Java做什么。 Eg you try to append an element to an already full Array. 例如,您尝试将元素追加到已经完整的Array中。

  • a new Array is allocated with the desired size; 分配了具有所需大小的新数组; this includes setting up the meta data 这包括设置元数据
  • a lock has to be set so the old Array doesn't change 必须设置一个锁,这样旧的Array才不会改变
  • all data is copied from the existing Array to the new Array; 将所有数据从现有阵列复制到新阵列; includes updating meta data; 包括更新元数据; note that both Arrays need to exist at the same time for this 请注意,为此需要两个数组同时存在
  • the original Array is removed (not sure of the right word here.) 原始数组被删除(不确定此处的正确单词。)
  • the lock is removed 锁被移除
  • If you just fiddle with pointers, you will loose the data. 如果只是摆弄指针,则会丢失数据。
  • You can easily copy the data using standard methods such as Add() and Remove() 您可以使用标准方法(例如Add()和Remove())轻松复制数据

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM