You can't call a function from within a struct definition. You should instead simply keep your first struct definition with the large string inside, and then do malloc(sizeof(p_msg)) when you want to create one.

Or you can keep it with the pointer inside, and remember to initialize that pointer with the result of malloc() every time you create a struct instance.

If you have a function taking the struct by pointer, you can do this:

int extMsg(p_msg *msgBuffer)
{
    msgBuffer->longSize = 12;
    msgBuffer->hello = malloc(12);
    snprintf(msgBuffer->hello, 12, "hello %d", 42);
    return 0;
}
Answer from John Zwinck on Stack Overflow
🌐
Reddit
reddit.com › r/c_programming › memory allocation for char array inside struct
r/C_Programming on Reddit: Memory allocation for char array inside struct
July 28, 2018 -

Hey friends,

I'm sure somebody on the internet jas alread answered this, but I honestly haven't found a suitable answer for me.

Let's say we have a struct like this:

typedef struct {
    char *name;
    int age;
} Human;

And a kind of "constructor" function like this:

Human *human_new(char *name, int age)
{
    Human *this = (Human *) malloc(sizeof(Human));

    this->name = name;
    this->age  = age;

    return this;
}

My question is, do I need to allocate memory for the char pointer name of the struct or is the assignment of this->name enough?

Top answer
1 of 5
25
My question is, do I need to allocate memory for the char pointer name of the struct or is the assignment of this->name enough? Depends on what you want to do. If you simply assign to this->name, then the object you've just allocated won't "own" the pointer or the contents of the string to which it points. It has merely borrowed the pointer. The string contents could change at any time, or the pointer could be invalidated by being freed, without the Human object even knowing. Borrowing pointers can indeed be useful in some cases, but it's almost certainly not what you want here. You probably want to strdup the name argument to create a completely new string with the same contents. You might even want to change name to be a const char *, to emphasise the fact that the value being passed is going to be copied, not borrowed. If you do create a whole new string for that name field, you will probably want to provide a destructor for your Human objects, e.g.: void human_free(Human *this) { free(this->name); free(this); } Also, on a completely different note, the cast in: Human *this = (Human *) malloc(sizeof(Human)); isn't necessary in C. Object pointers can be converted to and from void pointers without casts.
2 of 5
5
Yes, you will need to allocate memory for whatever you want to put in the name of the struct. malloc(sizeof(Human)) will allocate enough space for a char pointer and an int, it won't allocate memory for the contents of name because it has no idea what the size will be. If you know the upper bound on the size of name, or are happy to enforce one, you could change the definition of the struct to: typedef struct { char name[100]; int age; } Human; Then when you call malloc(sizeof(Human)) you'll get enough space for a 'string' containing up to 100 characters (only 99 usable because of the null terminator) and an int. If you do that, it would probably be sensible to define the maximum length of a name as #define MAX_HUMAN_NAME_LENGTH 100 to be clearer and so you only have to change it in one place.
Discussions

Char, Malloc, and Struct Arrays - Stack Overflow
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... Im still learning C and I have a question regarding char arrays, malloc and structures. More on stackoverflow.com
🌐 stackoverflow.com
c - Allocate memory for char array pointer of struct inside function - Stack Overflow
I was looking around for about one day on how to solve my problem. I find solutions for problems similar to mine but when I apply changes error : error: request for member 'mark' in something not a More on stackoverflow.com
🌐 stackoverflow.com
c - Malloc an array inside a struct - Stack Overflow
First of all, don't cast result of malloc. You only need to do that in C++. In C, it can actually hide potential problems. Second of all, you need to allocate (or statically declare) your structure. Third, c->stock doesn't exist. You probably meant c->string. typedef struct { char *string; ... More on stackoverflow.com
🌐 stackoverflow.com
May 19, 2015
Structs???? Malloc??? Pointers to Malloc and Structs??
I'm learning C++ right now and I am having a very hard time understandind structures, dynamic memory, and pointers to the latters. I understand this is how you write a pointer: ... though I'm not sure how you are supposed to use syntax for malloc, it's confusingint array[10] = (10 * sizeof(int); ... More on cplusplus.com
🌐 cplusplus.com
June 6, 2014
Top answer
1 of 2
37

Allocating works the same for all types. If you need to allocate an array of line structs, you do that with:

struct line* array = malloc(number_of_elements * sizeof(struct line));

In your code, you were allocating an array that had the appropriate size for line pointers, not for line structs. Also note that there is no reason to cast the return value of malloc().

Note that's it's better style to use:

sizeof(*array)

instead of:

sizeof(struct line)

The reason for this is that the allocation will still work as intended in case you change the type of array. In this case this is unlikely, but it's just a general thing worth getting used to.

Also note that it's possible to avoid having to repeat the word struct over and over again, by typedefing the struct:

typedef struct line
{
    char* addr;
    char* inst;
} line;

You can then just do:

line* array = malloc(number_of_elements * sizeof(*array));

Of course don't forget to also allocate memory for array.addr and array.inst.

2 of 2
10

For what you have described, You do not need to allocate memory for your struct, rather, you need to allocate memory for the members char *addr;, and char *inst;. If you want to have a single copy of that structure, the first section of code illustrates how to initialize, and assign values. If you want an array, the second code example illustrates the differences.

This illustrates how to allocate memory for the members of a single struct line:

typedef struct
{
    char* addr;
    char* inst;
}LINE;

LINE line;  

int main(void)
{   

    strcpy(line.addr, "anystring"); //will fail
    line.addr = malloc(80);
    line.inst = malloc(80);
    strcpy(line.addr, "someString");//success;
    strcpy(line.inst, "someOtherString");//success;

}

For array of struct line...

typedef struct
{
    char* addr;
    char* inst;
}LINE;  //same struct definition

LINE line[10]; //but create an array of line here.

int main(void)
{   
    int i;
    
    for(i=0;i<10;i++)
    {
      line[i].addr = malloc(80);
      line[i].inst = malloc(80);
    }

    for(i=0;i<10;i++)
    {
        strcpy(line[i].addr, "someString");
        strcpy(line[i].inst, "someOtherString");
    }
    //when done, free memory
    for(i=0;i<10;i++)
    {
        free(line[i].addr);
        free(line[i].inst);
    }      


}

Added to address comment
Addressing the comment under this answer from @Adam Liss, the following code illustrates the following improvements using strdup(): 1) Uses only memory needed. 2) Performs memory creation and copy operations in one step, so the the following blocks:

for(i=0;i<10;i++)
{
  line[i].addr = malloc(80);
  line[i].inst = malloc(80);
}

for(i=0;i<10;i++)
{
    strcpy(line[i].addr, "someString");
    strcpy(line[i].inst, "someOtherString");
}

Become:

for(i=0;i<10;i++)
{
  line[i].addr = strdup("someString");
  line[i].inst = strdup("someOtherString");
}

One more note: Error handling was not included in examples above to avoid muddling up focus on the main concepts: But for the sake of completeness, because both malloc() and strdup() can fail, actual usage for each of these two functions, should include a test before using, eg:

Rather than

  line[i].addr = strdup("someString");
  line[i].inst = strdup("someOtherString");

The code should include

  line[i].addr = strdup("someString");
  if(!line[i].addr)
  {
      //error handling code here
  }
  line[i].inst = strdup("someOtherString");
  if(!line[i].inst)
  {
      //error handling code here
  }
🌐
Stack Overflow
stackoverflow.com › questions › 22390713 › char-malloc-and-struct-arrays
Char, Malloc, and Struct Arrays - Stack Overflow
for (i=0;i<20;i++) { info->name[i]=(char *)malloc(sizeof(char)*20); } Also, you are treating your struct pointer info as an array:
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 170620-dynamic-string-array-inside-struct.html
Dynamic string array inside a struct.
Usually when using an array of strings I'd implement it like this. ... char **arr = malloc(25 * sizeof(char)); for(size_t i = 0 ; i < 250 ; i++) arr[i] = malloc(250); Where 25 is the amount of elements and 250 is the size of the largest string I would want to store?
🌐
Linux Hint
linuxhint.com › array-of-structs-malloc
How to Use Malloc Function to Create Array of Structs – Linux Hint
If you don’t want to put a limit on the number of characters for the employee name then you can simply take the input first for the employee name inside the for loop within a new variable and then pass that variable size in the malloc function. The struct data type in C programming provides better performance when we have to deal with small groups of the same values. In this write-up, we have discussed the creation of structs with arrays using the dynamic memory function that is malloc() function.
🌐
LinuxQuestions.org
linuxquestions.org › questions › programming-9 › [c]-malloc-with-struct-char-**variablelengtharray-4175460334
[SOLVED] [c] malloc with struct->char **variablelengtharray
I've had a bad case of coders block for quite some time, and honestly, I'm just tired of searching, reading,reviewing,examing with gdb, cgdb, ddd...
Find elsewhere
🌐
Diveintosystems
diveintosystems.org › book › C2-C_depth › structs.html
Dive Into Systems
In examining the last example, start by considering the type of the outermost variable (p2 is a pointer to a struct personT). Therefore, to access a field value in the struct, the programmer needs to use → syntax (p2→name). Next, consider the type of the name field, which is a char *, used ...
🌐
Hopto
ssjools.hopto.org › char › memory › dynamic
Dynamic memory management — CHaR
From C99, it is possible to have a structure type whose final member is an array of unspecified length. For example, our person representation above could be defined as: ... The structure can now be allocated all at once, with the name tacked onto the end, if we allocate sufficient additional space: #include <stdlib.h> #include <string.h> struct person *make_person(const char *name, int day, int month, int year) { // Allocate space for the whole structure. size_t len = strlen(name) + 1; struct person *r = malloc(sizeof *r + len); if (!r) return NULL; // Assign fields.
🌐
Nyu-cso
nyu-cso.github.io › notes › 07-structs_malloc_2d.pdf pdf
Strings, Structs, malloc, 2D arrays Jinyang Li
• structs, malloc, 2D array · C Strings · Strings · • String is represented as an array of chars. – Array has no space to encode its length. • How to determine string length? – possible solu<on: explicitly pass an int represen<ng length · // tolower_string turns every character in character array s ·
🌐
Cplusplus
cplusplus.com › forum › beginner › 134883
Structs???? Malloc??? Pointers to Malloc and Structs??
June 6, 2014 - malloc has no place in C++. It's a C function and should not be used in C++ because it is type unaware and will not work with complex types. The C++ alternative is the new and delete keywords... but even those you should avoid using. C++ offers a 'vector' class which effectively is a resizable array, removing the need to dynamically allocate arrays manually. Additionally... using a char* to have a string is a bad idea.
🌐
Dartmouth College
cs.dartmouth.edu › ~campbell › cs50 › dynamicmem.html
Pointers and Dynamic Memory Allocation
calloc() which dynamically allocates memory - “c” stands for contiguous allocation. calloc is typically used to allocate contiguous space for arrays. The memory is with all bits set to zero/ char arrays to NULL. malloc() which dynamically allocates memory - “m” stands for memory.
🌐
HowStuffWorks
computer.howstuffworks.com › tech › computer software › programming
Pointers to Structures - The Basics of C Programming | HowStuffWorks
March 8, 2023 - Using the array of pointers allows the array to take up minimal space until the actual records are allocated with malloc statements. The code below simply allocates one record, places a value in it, and disposes of the record to demonstrate ...
🌐
LabEx
labex.io › tutorials › c-how-to-manage-memory-for-char-types-in-c-510337
How to manage memory for char types in C | LabEx
typedef struct { char* buffer; size_t size; size_t used; } MemoryArena; MemoryArena* create_memory_arena(size_t initial_size) { MemoryArena* arena = malloc(sizeof(MemoryArena)); arena->buffer = malloc(initial_size); arena->size = initial_size; arena->used = 0; return arena; } char* arena_allocate(MemoryArena* arena, size_t size) { if (arena->used + size > arena->size) { return NULL; } char* result = arena->buffer + arena->used; arena->used += size; return result; }
🌐
Quora
quora.com › How-do-I-dynamically-allocate-a-char-array-using-a-malloc-function-in-C
How to dynamically allocate a char array using a malloc function in C - Quora
In order to allocate memory dynamically using C language the following code will be enough: char *s = (char *)malloc(20 * sizeof(char)); The above line allocates memory for storing 20 characters or in fact 19 ch...