gpt4 book ai didi

c++ - 为堆栈和堆指针重新分配内存

转载 作者:太空宇宙 更新时间:2023-11-04 15:11:43 25 4
gpt4 key购买 nike

我开发了一个阻塞队列类如下

class Blocking_queue
{
public:
Blocking_queue();

int put(void* elem, size_t elem_size);
int take(void* event);

unsigned int get_size();

private:

typedef struct element
{
void* elem;
size_t elem_size;
struct element* next;
}element_t;

std::mutex m_lock;
std::condition_variable m_condition;
unsigned int m_size;
element_t* m_head;
element_t* m_tail;

};

我希望该类尽可能通用,所以我使用了一个空指针,该指针在元素添加到队列时分配并在从队列中移除时释放。

int Blocking_queue::take(void* event)
{
element_t* new_head = NULL;
int ret = 0;

// Queue empty
if(nullptr == m_head)
{
// Wait for an element to be added to the queue
std::unique_lock<std::mutex> unique_lock(m_lock);
m_condition.wait(unique_lock);
}

if(nullptr == realloc(event, m_head->elem_size))
{
ret = -1;
}
else
{
// Take element from queue
memcpy(event, m_head->elem, m_head->elem_size);
ret = m_head->elem_size;
new_head = m_head->next;
free(m_head->elem);
free(m_head);
m_head = new_head;
if(nullptr == m_head)
{
m_tail = nullptr;
}
m_size -= 1;
}
return ret;
}

如果队列为空,take() 函数会等待 m_condition 直到添加新元素。

必须在释放元素之前提供一个指针事件来复制元素的内容。

为确保给定指针具有复制元素内容的正确大小,我根据其大小重新分配了指针。

我遇到的问题是它不允许传递函数的语言环境变量,因为它是在堆栈上分配的。

如果我这样做的话

void function()
{
unsigned int event = 0;

queue->take(&event);
}

我将在重新分配时遇到无效的旧大小错误。

因此,如果我传递一个空指针或一个分配给堆的变量,它会起作用,但如果我传递一个堆栈变量地址,它就不会起作用。

有没有办法允许将堆栈变量地址传递给take() 函数?

最佳答案

Is there a way to allow stack variable address to be passed to take() function ?

简短的回答是否定的。 malloc()/free()/realloc()只能使用堆分配的内存;它们不适用于堆栈分配的内存。

至于如何解决这个问题,我认为需要重新设计。我的第一个建议是尽可能远离(void *)。 -- void 指针极不安全且难以正确使用,因为编译器对它们指向的内容一无所知,因此当程序员做错事情时不会产生错误;这会导致很多运行时问题。它们更像是一种 C 语言结构,在 C++ 中仍然受支持以提供 C 兼容性,但 C++ 有更好、更安全的方法来做同样的事情。

特别是,如果您的队列中的所有数据元素都应为同一类型,那么显而易见的事情就是使您的 Blocking_queue 类以该类型作为模板参数进行模板化;然后用户可以指定例如Blocking_queue<MyFavoriteDataType>并使用他喜欢的任何类型,并提供易于使用的按值语义(类似于 std::vector 和 friend 提供的语义)

如果你想允许混合不同类型的数据元素,那么最好的做法还是上面的方法,但是为对象定义一个公共(public)基类,然后你可以实例化一个Blocking_queue<std::shared_ptr<TheCommonBaseClass> >。将接受指向该基类的任何子类的任何堆分配对象的共享指针的对象。 (如果你真的需要将共享指针传递给堆栈分配的对象,你可以通过为共享指针定义一个自定义分配器来做到这一点,但请注意,这样做会打开对象生命周期不匹配问题的大门,因为堆栈对象可能会在它们从队列中移除之前被销毁)

关于c++ - 为堆栈和堆指针重新分配内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56501067/

25 4 0
文章推荐: android - 为 Android 应用程序设置 ActionBarSherlock 主题
文章推荐: html - 图标字体在 Firefox 中不起作用
文章推荐: html -
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com