【问题标题】:Malloc of arrays and structs within a struct结构中的数组和结构的 Malloc
【发布时间】:2011-07-24 20:36:19
【问题描述】:

如何分配位于另一个结构中的结构?

我还想在一个结构中 malloc 一个项目数组,然后在需要时重新分配这个数组,这是如何正确完成的?

你能举一个声明结构然后上面的例子吗?

我有点不确定事情的顺序。

是否会释放结构中的数组,然后释放结构本身,是否必须在创建结构时分配结构,然后分配/声明其字段等?

【问题讨论】:

    标签: c struct malloc realloc


    【解决方案1】:

    包含在另一个struct 中的struct 包含在副本中,因此您不必单独对其进行malloc。如果struct 包含指向另一个struct 的指针,那么您可以考虑为它动态分配内存。

    struct Point2d
    {
        float x;
        float y;
    };
    
    struct Rect
    {
        struct Point2D a;
        struct Point2D b;
    };
    
    struct LinkedListNode
    {
        struct LinkedListNode* next;
        int value;
    };
    

    struct Rect 中,struct Point2D 元素被插入到struct Rect 中,您不必为它们动态分配内存。相反,在struct LinkedListNode 中,下一个元素由指针引用,并且必须动态分配内存。

    这两个版本都有用,视情况而定。没有正确的方法来管理内存,这取决于您的使用情况。

    同样的情况也发生在数组的情况下。如果您的数组是静态大小的,那么它可以直接包含在struct 中。但是,如果大小可以变化,则必须在 struct 中存储一个指针。

    struct Header
    {
        char magic[4];
        unsigned int width;
        unsigned int height;
    };
    
    struct Buffer
    {
        char* data;
        unsigned int size;
        unsigned int capacity;
    };
    
    struct Buffer* buffer_init()
    {
        struct Buffer* buffer = (struct Buffer*)malloc(sizeof(struct Buffer));
        buffer->data = 0;
        buffer->size = 0;
        buffer->capacity = 0;
    }
    
    void buffer_grow(struct Buffer* buffer, size_t capacity)
    {
        if (capacity > buffer->capacity)
        {
            buffer->data = realloc(buffer->data, capacity);
            buffer->capacity = capacity;
        }
    }
    
    void buffer_append(struct Buffer* buffer, const char* data, unsigned int dataLen)
    {
        if (dataLen + buffer->size > buffer->capacity)
            buffer_grow(MAX(dataLen + buffer->size, buffer->capacity * 2));
    
        memcpy(buffer->data + buffer->size, data, dataLen);
        buffer->size += dataLen;
    }
    

    realloc 函数只进行浅拷贝,即拷贝指针值,而不拷贝指向的对象。还有一次,你如何处理它取决于你的应用程序。

    【讨论】:

    • 谢谢。我想在结构内有一个动态数组。那么如果 struct Point2D 出于某种原因有一个数组,然后我们在一个 rect 结构中创建一个 Point2D,这是怎么做的呢?
    【解决方案2】:
    typedef struct _A
    {
      int *arr;
      int arrCount;
    } A;
    
    void Construct_A(A *a, int arraySize)
    {
      a->arrCount = arraySize;
      a->arr = (int*)malloc(sizeof(int)*arraySize);
    }
    
    void Destruct_A(A *a)
    {
      free(a->arr);
      a->arr = 0;
    }
    
    typedef struct _B
    {
      A *a;
    } B;
    
    void Construct_B(B *b, int arraySize_A)
    {
      b->a = (A*)malloc(sizeof(A));
      Construct_A(b->a);
    }
    
    void Destruct_B(B *b)
    {
      Destruct_A(b->a);
      free(b->a);
      b->a = 0;
    }
    
    void main()
    {
      B b;
      Construct_B(&b, 10);
    
      // Use b and b->a
    
      Destruct_B(&b);
    }
    

    【讨论】:

      【解决方案3】:

      以下是结构体中嵌套结构体和数组的示例。在free 外部结构之前,您会注意到必须如何处理嵌套元素,否则最终会导致内存泄漏。

      typedef struct Base Base;
      struct Base
      {
        int x;
      };
      
      typedef struct Sample Sample;
      struct Sample
      {
        Base base;
        int size;
        int *arr;
      };
      
      // Create the sample struct
      
      Sample *createSample()
      {
        Sample sample = malloc(sizeof(Sample));
        if(sample == NULL)
        {
          return NULL;
        }
        sample->base = malloc(sizeof(Base));
        if(sample->base == NULL)
        {
          free(sample);
          return NULL;
        }
        sample->base->x = 0;
        sample->size = 0;
        sample->arr = NULL;
        return sample;
      }
      
      // Adding element to the array
      
      void addItemToSample(Sample *sample, int item)
      {
        if(sample == NULL)
        {
          return;
        }
        int *arr = realloc(sample->arr, sizeof(int) * (sample->size + 1));
        if(arr == NULL)
        {
          return;
        }
        arr[sample->size++] = item;
        sample->arr = arr;
      }
      
      // Freeing the struct
      
      void freeSample(Sample *sample)
      {
        // Free deep elements first
        free(sample->base);
        free(sample->arr);
        // Free outer
        free(sample);
      }
      

      【讨论】:

        【解决方案4】:

        它的可读性不是很强,但有时人们会创建一个包含一个计数成员和一个最终单元素数组成员的结构。然后有一个特殊的工厂方法,它分配足够的空间,以便您可以写入以计算数组中的元素。显然数组成员可以是任何类型。

        typedef struct {
            int count;
            int elements[1];
        } int_array;
        
        int_array* allocate_int_array(int count)
        {
            int_array* mem = (int_array*)malloc(sizeof(int_array) + (count - 1) * sizeof(int));
            if (mem)
                mem->count = count;
            return mem;
        }
        

        【讨论】:

          【解决方案5】:
          typedef struct _A { int i; } A;
          typedef struct _B { int j;  A a} B;
          

          要获得一个 B:

          B *b = malloc(sizeof(B));
          

          获取 B 的数组:

          B *b = malloc(sizeof(B) * arrayLength);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-01-20
            • 1970-01-01
            • 2015-07-30
            • 2012-09-19
            • 2023-04-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多