【问题标题】:queue by copy or by reference按副本或按引用排队
【发布时间】:2018-11-27 11:20:07
【问题描述】:

有两种方式可以实现队列行为:

  1. 按副本排队 复制队列意味着发送到队列的数据被逐字节复制到队列中。 排队。

  2. 按引用排队 引用队列意味着队列只保存指向发送到队列的数据的指针。 队列,而不是数据本身。

我想问如果通过复制排队包含指针的结构将创建一个副本或直接访问指向的内存。 谢谢。

【问题讨论】:

  • 是你自己的实现还是来自某个库的队列?
  • 不确定“通过复制包含指针的结构进行排队将创建副本或直接访问指向的内存”是什么意思
  • 这是freertos api中的队列
  • 如果它是一个通用队列实现,我猜它的“复制”功能只适用于一层深度。
  • 我的意思是,如果您有 2 个任务并在第一个任务中使用 xQueueSend(),在第二个任务中使用 xQueueReceive(),然后尝试取消引用第二个任务中的指针并更改数据会影响第一个任务中的数据??

标签: c freertos


【解决方案1】:

您的问题的答案是视情况而定。

假设下一个结构:

struct a_t
{
  int id;
  char *name;
};

将结构的一个实例分配给另一个实例时,会复制源,但它是浅拷贝。

一般来说,当内部指针指向动态分配的块,并且分配的唯一指针在结构中时,我会说它需要一个深拷贝,如果你只是分配内存可能会泄漏......

在某些情况下,浅拷贝就足够了:

//assume you have a dictionary, or other container to save all names:
char dictionary[][] = {"name1","name2","name3"};
a_t a1 {1, dictionary[0]};
a_t a2=a1; //shallow copy is enough

如果将一个实例复制到另一个实例,内存不会泄漏,因为所有指针都保存在字典中。

在其他情况下它不会,因此您应该执行深层复制,主要是当结构成员在一个实例中被释放并且您不希望它影响另一个实例时。

如下所示:

void fill(a_t **ppa, int id, const char* name)
{ 
  a_t *pa = malloc(sizeof(a_t));
  pa->id = id;
  pa->name = strdup(name);
  erase(*ppa);
  *ppa = pa;
} 
void erase(a_t *pa)
{
  if(pa){
    free(pa->name);
    free(pa);
  } 
}

【讨论】:

  • 是的 - 这是另一个好处 - 有些东西不能被复制,或者这样做非常昂贵/有风险。
猜你喜欢
  • 1970-01-01
  • 2011-12-03
  • 2012-06-21
  • 2020-06-08
  • 1970-01-01
  • 2013-08-15
  • 2019-12-03
  • 1970-01-01
相关资源
最近更新 更多