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

xcb内存管理:是否应该在迭代器中释放数据字段?

如何解决xcb内存管理:是否应该在迭代器中释放数据字段?

在xcb中的某些列表属性上有一组用于迭代的函数。它们都以iterator结尾。例如,xcb_setup_roots_iterator。并且有相应的函数next或其他函数结尾进行迭代。

问题来了: 当我不再需要数据时,应该在迭代器的free字段上调用data吗?

这里是一个样本。

  int screen_num;
  xcb_connection_t *connection = xcb_connect(NULL,&screen_num);
  const xcb_setup_t *setup = xcb_get_setup(connection);

  xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
  for (; iter.rem; xcb_screen_next(&iter)) {
    xcb_screen_t *screen = iter.data;
    /*do something with screen*/
  }
  /*should I free iter.data here?*/

我知道iter在堆栈中,因此它将被自动销毁。但是其中的data呢?按照我的想法,xcb会创建它,并且在使用它后我再也不会将其传递回xcb,因此xcb没有机会释放它,因此我应该手动释放它以避免内存泄漏。

搜索文档和网络后,我仅找到有关内存管理的一些有限信息,例如: 我应该始终释放xcb_wait_for_event的返回值。 那其他地方呢? xcb中的内存管理的一般原理是什么?

解决方法

简短版本:不,您不应该释放它。

长版: 这是xcb_screen_next的实现:

void
xcb_screen_next (xcb_screen_iterator_t *i)
{
    xcb_screen_t *R = i->data;
    xcb_generic_iterator_t child;
    child.data = (xcb_screen_t *)(((char *)R) + xcb_screen_sizeof(R));
    i->index = (char *) child.data - (char *) i->data;
    --i->rem;
    i->data = (xcb_screen_t *) child.data;
}

如您所见,这只会起到一些指针魔术的作用,以计算屏幕的大小,然后将指针增加该数量,即新的data成员指向刚好超出最后一个屏幕末尾的位置。 换句话说:内存中的所有屏幕都在单个内存中紧挨着。

我应该始终释放xcb_wait_for_event的返回值。那其他地方呢? xcb中的内存管理的一般原理是什么?

xcb确实不执行任何解析。相反,它将在线协议描述为C struct,并提供了一些使用这些协议的便捷方法。这意味着将从连接中读取单个X11“数据包”并将其放入一个大内存区域。其他所有东西只是进入各个字段的指针魔术。

由于您正在询问xcb_screen_t:这是xcb_setup_t的一部分。连接到X11服务器时,会收到一个xcb_setup_t。这是一个很大的分配,您可以使用xcb_get_setup进行访问。此内存归libxcb所有,并由xcb_disconnect()释放。

“包”还有什么?好吧,每个答复,事件和错误都是一个数据包。因此,您必须释放从xcb_wait_for_event()得到的一切,而且还要释放xcb_*_reply()。不需要释放其他任何东西。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。