如何分配内存并使用指向二维数组的指针填充结构

时间:2019-02-15 04:28:49

标签: c pointers multidimensional-array struct malloc

我需要使用指向二维char数组的指针为struct分配足够的内存。然后填充结构

struct Dataset
{
    int size;
    char (*items)[][MAX_STRING_LENGTH];
};

我试图只为结构和二维数组分配内存,如下所示

struct Dataset * dataset = malloc( sizeof (Dataset) + (2 * sizeof(char[2][15])) )

然后像这样填充二维数组,但是我做不到

strcpy((*dataset->items)[0][0], "HELLO WORLD");

3 个答案:

答案 0 :(得分:0)

让我们了解char (*items)[][MAX_STRING_LENGTH];是什么。

指向MAX_STRING_LENGTH个字符的数组的指针。

因此,item将需要4或8个字节,具体取决于您的平台。

+号后分配给您的任何东西都是浪费:

struct Dataset * dataset = malloc( sizeof (Dataset) **+** (2 * sizeof(char[2][15])) )

将其更改为:

struct Dataset * dataset = malloc( sizeof ( struct Dataset));

现在,您需要指针item指向正确的地方,

因此分配内存并指向它:

dataset->item = malloc(sizeof(char[2][MAX_STRING_LENGTH]));

现在您有item指向有效内存。请使用它。

// --------------------------------------------- ---------------

没有答案:  我坚信您的结构声明本身存在缺陷。如果您可以发表想要达成的目标,那将会有所帮助。

答案 1 :(得分:0)

至少有两种方法可以做到这一点。一种是问题中概述的方法,它带有指向char的2D数组的指针。另一个使用灵活数组成员(FAM)。

指向2D数组的指针

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MAX_STRING_LENGTH = 15 };

struct Dataset
{
    int size;
    char (*items)[][MAX_STRING_LENGTH];
};

int main(void)
{
    int rows = 3;
    struct Dataset *dataset = malloc(sizeof(struct Dataset) + (sizeof(char[rows][MAX_STRING_LENGTH])));
    dataset->size = rows;
    dataset->items = (void *)((char *)dataset + sizeof(struct Dataset));

    for (int i = 0; i < rows; i++)
        sprintf((*dataset->items)[i], "Row 0x%.*X", 2*(i+2), i);

    for (int i = 0; i < rows; i++)
        printf("Row %d: [%s]\n", i+1, (*dataset->items)[i]);

    free(dataset);
    return 0;
}

这将为结构和2D数组分配足够的空间。问题中未显示的第一步是确保items成员已初始化;它必须指向某处,并且您在数组结构后分配了空间。第二个关键步骤是正确使用指向2D数组的指针。请注意,二维字符数组的对齐没有复杂性。如果是其他类型的2D数组,则可能需要担心对齐问题,尽管很有可能结构的大小正确,因此对齐问题不大(除非您使用具有32位地址的编译器int和16字节的long doublelong double必须在16字节的边界上对齐-我不确定是否存在这样的编译器)。

输出为:

Row 1: [Row 0x0000]
Row 2: [Row 0x000001]
Row 3: [Row 0x00000002]

灵活阵列成员

这使用一个前导尺寸为空的数组作为具有至少一个其他成员的结构的最后一个成员。这次,不需要计算偏移量,也不需要使用特殊的符号来访问数组的元素:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MAX_STRING_LENGTH = 15 };

struct Dataset
{
    int size;
    char items[][MAX_STRING_LENGTH];
};

int main(void)
{
    int rows = 3;
    struct Dataset *dataset = malloc(sizeof(struct Dataset) + (sizeof(char[rows][MAX_STRING_LENGTH])));
    dataset->size = rows;

    for (int i = 0; i < rows; i++)
        sprintf(dataset->items[i], "Row 0x%.*X", 2*(i+2), i);

    for (int i = 0; i < rows; i++)
        printf("Row %d: [%s]\n", i+1, dataset->items[i]);

    free(dataset);
    return 0;
}

此代码的输出与其他代码的输出相同。

答案 2 :(得分:0)

我发现我的错误有两个错误。

第一个。
我应该将第一个数组维初始化为零,之后再用malloc来更改其大小,例如

struct Dataset
{
    int size;
    char (*items)[0][MAX_STRING_LENGTH];
};

第二个
要更改某个位置的数组值,我无法使用(*dataset->items)[x][y]。我必须删除*

strcpy((dataset->items)[0][0], "HELLO WORLD");