简体   繁体   中英

How to allocate memory and fill struct with pointer to bidimensional array

I need to allocate enough memory for struct with a pointer to a bidimensional char array. And then fill the struct

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

I tried to allocate memory only for the struct and the bidimensional array as follows

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

And then fill the bidimensional array like this, but I'm not being able to do it

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

Lets Understand What char (*items)[][MAX_STRING_LENGTH]; is.

It is pointer to array of array of MAX_STRING_LENGTH characters .

So , item will require 4 or 8 bytes depending on your platform.

Whatever you are allocating here after + sign is a waste :

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

Change this to :

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

Now you need your pointer item to pointing somewhere right,

So allocate memory and point to it:

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

Now you have item pointing to valid memory.Go Use it.

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

Not an answer: I strongly believe your structure declaration itself is flawed. If you could post want to achieve then it will helpful.

There are at least two ways to do this. One is the way outlined in the question, with a pointer to a 2D array of char . The other uses a flexible array member (FAM).

Pointer to 2D array

#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;
}

This allocates enough space for the structure and the 2D array. The first key step not shown in the question is ensuring that the items member is initialized; it has to point somewhere, and you allocated space after the structure for the array. The second key step is using the pointer-to-2D-array correctly. Note that there is no complication with alignment for the 2D array of characters. Were it a 2D array of some other types, you might have to fret about alignment, though the chances are that the structure will be the right size such that alignment isn't an issue (unless perhaps you use a compiler with 32-bit addresses and int and 16-byte long double and long double must be aligned on a 16-byte boundary — I'm not sure such a compiler exists).

The output is:

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

Flexible Array Member

This uses an array with an empty leading dimension as the last member of a structure with at least one other member. This time, there is no need to compute an offset, nor is there need to use special notations to access the elements of the array:

#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;
}

The output from this code is the same as the output from the other code.

I've found my errors two errors.

First one.
I should initialize the first array dimension on zero, to later change his size with malloc , like this

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

Second One
To change the value of the array on a position I can't user (*dataset->items)[x][y] . I have to remove the *

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM