【问题标题】:Redirecting a list of pointers from one structure to another将指针列表从一个结构重定向到另一个结构
【发布时间】:2016-12-29 18:14:46
【问题描述】:

我定义了一个书本结构,其中包含指向章节结构的指针列表:

typedef struct chapter {
  int pages;
  //much more information
} chapter;

typedef struct book {
  chapter* all_chapter;
  int nb_chapter;
} book;

现在在我的函数中,我分配了 2 个 book 类型的变量。我正在处理 NULL 指针,但为了保持代码简短,我将其省略!

book* first_book = malloc(sizeof(book));
first_book->nb_chapter = 5;
first_book->all_chapter = malloc(first_book->nb_chapter * sizeof(chapter));

book* snd_book = malloc(sizeof(book));

所以现在我希望在某些情况下第二个变量 snd_book 获取第一本书的所有章节指针,但不是复制它们,而是指向分配的相同内存,这意味着如果我然后释放 snd_book->chapter 然后 @987654324 @ 也是空的。

但如果我这样做了

   snd_book->chapter = first_book->all_chapter; 

然后一切都被复制了。

我是否需要将章节定义为二维指针或如何实现?

【问题讨论】:

  • 不,snd_book->all_chapter = first_book->all_chapter; 不会复制 “所有内容”。您是如何确定会出现这种情况的?
  • snd_book->chapter 似乎也是语法错误,你在做什么?
  • 正如 UnholySheep 已经提到的,指针分配不会复制所有内容。但它确实复制了分配的地址,所以如果你打电话给某事。喜欢free( first_book->all_chapter ); first_book->all_chapter = NULL;`snd_book 中的指针将保持以前的状态,但访问它会调用 UB。为避免这种情况,您确实需要指向指针的指针
  • 您能详细说明您要达到的目标吗?

标签: c pointers


【解决方案1】:

现状

书本结构不包含指向章节的指针列表。它包含一个指向章节或章节数组的指针。

确实如此,在做的时候

    snd_book->all_chapter = first_book->all_chapter;  

两本书将共享完全相同的内容(最终您可以假装第二本书的章节更少,但这是唯一可能的区别)。

预期情况:独立的可共享章节

如果您只想共享某些章节,则需要使用指向章节的指针而不是指向章节的指针:

typedef struct book {
    chapter** all_chapter;
    int nb_chapter;
} book;

但这使得初始化更加复杂:

// initialize an array of pointer to chapter  
first_book->all_chapter = calloc(first_book->nb_chapter, sizeof(chapter*));
// initialize each pointer in the array: 
for (int i=0; i< first_book->nb_chapter; i++) 
    first_book->all_chapter[i] = malloc (sizeof(chapter));

当然,您需要像在真实代码中一样处理空指针;-)

确实,这一切有点像二维数组,其中第二维始终为 1。但实际上它是一维指针数组。

通过这种方法,您只能共享选定的章节。

然而,这是一个冒险的结构:如果第一本书会清除一章,那么第二本书也会清除它。但是,如果第一本书释放了一个章节,释放了它的内存,那么第二本书就不会意识到并且可能仍然使用不应再被触及的内存。更糟糕的是:如果第二本书有一些原创的(自己的章节)和一些共享的,你将无法确定哪些应该被释放,哪些会被另一本书释放。

【讨论】:

  • 感谢克里斯托夫的解释!我知道像这样的场景显示了您提到的风险结构,但在我的代码中我处理的方式不同,这只是为了保持示例简短。
  • @malajedala 我已经说明了差异。例如,您可以通过使用本章中的引用计数来处理风险。当一本书丢弃一个章节时,如果它的引用计数为 1(没有其他书籍正在使用它),它将释放该章节,并在其他情况下减少计数器。
【解决方案2】:
book* first_book = malloc(sizeof(book));
first_book->nb_chapter = 5;
first_book->all_chapter = malloc(first_book->nb_chapter * sizeof(chapter));

book* snd_book = malloc(sizeof(book));
snd_book->all_chapter = first_book->all_chapter;

现在你有两个指向相同章节的指针

你有来自 snd_book 和 first_book 的指针 all_chapter 指向你分配的同一个 blob。没有从地址复制任何部分。

IOW

first_book->all_chapter = malloc(first_book->nb_chapter * sizeof(chapter))

创建一个章节数组,first_book-&gt;all_chapter 指向第一个章节。

snd_book->all_chapter = first_book->all_chapter;

使snd_book-&gt;all_chapter 指向与first_book-&gt;all_chapter 指向的相同。

您也许还应该将章节数存储在 snd_book 中以了解有多少章节,因为指针不传达该信息。

snd_book->nb_chapter = first_book->nb_chapter;

【讨论】:

  • 感谢您一步一步的解释,现在我认为这更清楚了。所以 snd_cook->all_chapter 只保留我使用 first_book->all_chapter 分配的内存。
猜你喜欢
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 2023-03-16
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多