-3

I checked Google but I cannot find any solution. I'm making a program and I need to use dynamic memory allocation. This is the struct I use

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

I want to allocate memory for members Array using dynamic memory allocation, on the internet in every sample it allocates memory for pointers, I cannot represent my array as a pointer too.

halfer
  • 19,824
  • 17
  • 99
  • 186
fx773d
  • 601
  • 1
  • 5
  • 3

1 Answers1

-1

I cannot represent my array as a pointer too.

There's no other way in C than to represent a dynamically allocated array of memory through a pointer.

I think your mental roadblock stems from the conception, that the data of the structure should be arranged in the order as defined in the structure. I'm sorry to tell, you, but this is not possible to do in C in a straightforward way.

Sure it's perfectly possible to have a data structure of the from

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

somewhere in memory. But there's no built-in support in C for this kind of binary data stream.

The best thing you can do, is have a number of helper pack/unpack functions that take an opaque pointer to some memory and can pack and unpack to C structures to work with.

Note that if you're looking for using that as a way to parse the contents of a file: DON'T! There lie only monsters and fear that way.


EDIT code sample

For example assume the following structure

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 */

You can pack that into a binary stream with the following function

/* 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;
}

Unpacking is straightforward

/* 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;
}

Exercise left for the reader: Write a function that frees a Foo structure.

datenwolf
  • 159,371
  • 13
  • 185
  • 298