【问题标题】:Dynamic Memory Allocation to a Struct's array. Program Closing [C]结构体数组的动态内存分配。程序关闭 [C]
【发布时间】:2014-01-25 15:11:08
【问题描述】:

我查了谷歌,但找不到任何解决方案。我正在制作一个程序,我需要使用动态内存分配。这是我使用的结构

struct profile {
   char *item;
   int lala;
   char *lolo;
} members[];

我想使用动态内存分配为成员数组分配内存,在互联网上的每个示例中它为指针分配内存,我也不能将我的数组表示为指针。

【问题讨论】:

  • 那为什么不将members声明为指针呢?
  • “将我的数组表示为指针”是什么意思?
  • “我需要尽快解决”,自动投反对票。
  • 首先亲爱的马丁,我确实需要尽快找到解决方案,这不是因为我的态度。 Joachim 先生,如果我将其声明为指针,我必须更改基于数组的 180 行,但我不知道该怎么做。
  • 数组和指针之间唯一的技术区别是sizeof(someArray) 将返回数组的大小,而sizeof(somePointer) 将返回指针的大小。除此之外,由于数组衰减为指针,它们可以互换使用。

标签: c malloc dynamic-memory-allocation calloc


【解决方案1】:

我也不能将我的数组表示为指针。

在 C 中除了通过指针表示动态分配的内存数组之外别无他法。

我认为你的心理障碍源于这样的概念,即结构的数据应该按照结构中定义的顺序排列。很抱歉告诉你,但这在 C 语言中是不可能的。

当然,完全有可能拥有 from 的数据结构

size_t length;
char data[];
size_t length2
char data2[];

在记忆中的某个地方。但是对于这种二进制数据流,C 语言没有内置支持。

您能做的最好的事情是拥有许多帮助打包/解包函数,这些函数将一个不透明的指针指向一些内存,并且可以打包和解包为 C 结构以使用。

请注意,如果您正在寻找使用它来解析文件内容的方法:不要!只有怪物和恐惧。


编辑代码示例

例如假设如下结构

typedef struct Foo {
    size_t name_len;
    char * name; /* since we know len, this doesn't need to be '\0' terminated */
    size_t bar_len;
    char * bar;  /* same as for name */
} Foo; /* typedef for the lazy */

您可以使用以下函数将其打包成二进制流

/* returns a pointer to memory dynamically allocated and filled
 * with a packed representation of the contents of a Foo struct.
 * Once no longer needed release the memory allocated using free()
 *
 * returns NULL in case of an error.
 */
void * fooPack(Foo const * const foo_data)
{
    assert( NULL != foo_data );

    size_t const foo_data_lenth =
          foo_data->name_len
        + foo_data->bar_len
        + 2 * sizeof(size_t);

    char * const packed = malloc( foo_data_length );
    if( NULL == packed ) {
        return NULL;
    }

    char * p = packed;

    *((size_t*)p) = foo_data->name_len;
    p += sizeof(size_t);

    memcpy(p, foo_data->name, foo_data->name_len);
    p += foo_data->name_len;

    *((size_t*)p) = foo_data->bar_len;
    p += sizeof(size_t);

    memcpy(p, foo_data->bar, foo_data->bar_len);

    return p;
}

拆包很简单

/* Unpacks a struct Foo with memory for name and bar allocated
 * to match the data found in the packed data buffer.
 *
 * returns 0 on success and a negative value on error
 */
int fooUnpack(Foo * const foo_data, void const * const packed)
{
    if( NULL == foo_data ) {
        return -1;
    }

    if( NULL == packed ) {
        return -2;
    }

    char const * p = packed;

    /* unpack name */

    size_t const name_len = *((size_t*)p);
    p += sizeof(size_t);

    char * name = malloc(name_len);
    if( NULL == name ) {
        return -3;
    }

    memcpy(name, p, name_len);
    p += name_len;

    /* unpack bar */

    size_t const bar_len = *((size_t*)p);
    p += sizeof(size_t);

    char * bar = malloc(bar_len);
    if( NULL == bar ) {
        free( name );
        return -4;
    }

    memcpy(bar, p, bar_len);

    /* fill in foo_data */

    foo_data->name_len = name_len;
    foo_data->name = name;
    foo_data->bar_len = bar_len;
    foo_data->bar = bar;

    return 0;
}

留给读者的练习:编写一个释放 Foo 结构的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    相关资源
    最近更新 更多