【问题标题】:C how to modify memory of structs that are inside other structsC如何修改其他结构内的结构的内存
【发布时间】:2013-05-21 09:01:28
【问题描述】:

如果我有两个结构:

typedef struct{
    unsigned int time;
    double rate;

}quote;

typedef struct{

    unsigned int freeSlots;
    unsigned int end;
    unsigned int start;
    unsigned int currSize;
    unsigned int maxSize;
    unsigned int startAt;
    //unsigned int currIndex;
    quote quoteBuffer[1];

}cbuf;

我想创建一个函数来修改 cbuf 中的 quoteBuffer 数组的大小,我该怎么做呢?我尝试了几种方法,但到目前为止都没有奏效。我不断返回相同的格式:

quote *newQuoteBuffer = malloc(sizeof(quote) * newSize);

如果我在某个地方已经有一个现有的 cbuf(例如,我们将它称为“a”,其中 a 是指向 cbuf 的指针):

a->quoteBuffer = newQuoteBuffer;

但这显然行不通。有什么提示吗?

【问题讨论】:

  • quote quoteBuffer[1]这有什么意义?
  • 你不能改变cbuf结构?那么quoteBuffer是一个指针吗?
  • 初始化 cbuf 结构中的引号数组。我想我也可以引用quoteBuffer []。但我使用了 1,因为稍后我将使用 malloc 修改大小。
  • 最好有一个指向引用的指针而不是数组。
  • @JoachimPileborg 如引用 *quoteBuffer;在 cbuf 结构内部?

标签: c arrays struct


【解决方案1】:

这个:

quote quoteBuffer[1];

应该是:

quote *quoteBuffer;

然后分配就可以了。

取消引用quote 如下所示:

a->quoteBuffer->time;

如果您稍后使用 malloc() 分配了多个引用元素,您可以像这样访问它们:

a->quoteBuffer[i].time;

【讨论】:

  • 如果我想用一个新的quoteBuffer替换当前的quoteBuffer,它只是cbuf->quoteBuffer = newBuffer?
  • 是的,但不要忘记先 free() 它,否则会造成泄漏。当然,如果不使用,将其初始化为 NULL 总是一个好主意。
  • @Devolus free() 首先是原始的quoteBuffer?所以 free(cbuf->quoteBuffer) 然后是 cbuf->quoteBuffer = newBuffer?
  • 是的。为了安全起见,您应该将其初始化为 NULL,然后在释放之前执行 if(a->buffer) free(a->buffer); a->buffer = malloc(new size);
【解决方案2】:

如果您不确定有多少元素会进入quoteBuffer,请维护一个相同的链表。为此

quote *quoteBuffer;

并根据需要继续在缓冲区中添加或删除元素。

【讨论】:

    【解决方案3】:

    我认为您错过了为什么有人将结构的最后一个元素作为单个元素数组的要点。这是在旧 C 代码中使用的一种技巧,用于使结构大小可变长度。

    您可以编写如下代码:

    Bitmapset *p = malloc(offsetof(Bitmapset, quoteBuffer) + n * sizeof(quote));
    

    然后你写这样的代码:

    p->quoteBuffer[0]
    

    最多:

    p->quoteBuffer[n-1]
    

    您不想像您猜的那样直接将指针分配给 quoteBuffer。

    那么,为什么要将 quoteBuffer 声明为: 引用quoteBuffer[1]; 代替 报价*报价缓冲区; ?

    这是因为您不想为quoteBuffer 单独分配。单个分配可用于整个 cbuf,包括内联引号数组。

    【讨论】:

      【解决方案4】:

      有两种方法。一种是在 cbuf 中使用指针,正如其他人提到的那样,通过更改

      quote quoteBuffer[1];
      

      quote* quoteBuffer;
      

      另一种是调整cbuf的大小:

      #include <stddef.h> // for offsetof
      
      struct cbuf* realloc_cbuf(struct cbuf* cbufp, size_t nquotes)
      {
          struct cbuf* new_cbufp = realloc(cbufp, offsetof(struct cbuf, quoteBuffer) + nquotes * sizeof *cbufp->quoteBuffer);
          if (!new_cbufp)
          {
              // handle out of memory here. cbufp is still intact so free it if you don't need it.
          }
          return new_cbufp;
      }
      
      void elsewhere(void)
      {
          struct cbuf* acbuf = NULL;
          acbuf = realloc_cbuf(1);
          acbuf = realloc_cbuf(10);
          // etc. 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-07
        • 1970-01-01
        • 1970-01-01
        • 2018-05-23
        • 2017-10-25
        • 1970-01-01
        • 2020-03-15
        相关资源
        最近更新 更多