Yes, it's a matter of style, because you'd expect sizeof(char) to always be one.

On the other hand, it's very much an idiom to use sizeof(foo) when doing a malloc, and most importantly it makes the code self documenting.

Also better for maintenance, perhaps. If you were switching from char to wchar, you'd switch to

Copywchar *p = malloc( sizeof(wchar) * ( len + 1 ) );

without much thought. Whereas converting the statement char *p = malloc( len + 1 ); would require more thought. It's all about reducing mental overhead.

And as @Nyan suggests in a comment, you could also do

Copytype *p = malloc( sizeof(*p) * ( len + 1 ) );

for zero-terminated strings and

Copytype *p = malloc( sizeof(*p) * len ) );

for ordinary buffers.

Answer from brainjam on Stack Overflow
🌐
Medium
csnotes.medium.com › malloc-in-c-for-int-and-char-c3677b857b65
Malloc in C, for int * and char * | by zihan | Medium
May 15, 2021 - In such cases, malloc comes and help us. Int and char have by default a fixed size of memory, 4 bits for an int and 8 for a char. When you need an array of ints or chars, you need to allocate memory for them in a row, and you need to tell your program exactly how many slots of ints or char ...
Discussions

c - Memory allocation for char array - Stack Overflow
If you're stuck with the archaic ... known at compile time, so you have to use dynamic memory allocation — malloc(), free() etc. ... First declare a pointer to a "char". Then ask (the system) for space to store your required number of values using malloc and then add elements to this "array". char * test; int num_of_elements ... More on stackoverflow.com
🌐 stackoverflow.com
September 7, 2015
Freeing a char array
Also, the printf statement needs to be before free, or you have a "use after free" problem. More on reddit.com
🌐 r/C_Programming
22
2
January 24, 2024
Memory allocation for char array inside struct
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. More on reddit.com
🌐 r/C_Programming
29
25
July 28, 2018
[C] Storing strings using an array of char pointers and malloc.
The malloc function allocates a block of memory of a specified size, and then returns a pointer to the first memory address of that block. If you are using malloc to allocate memory for a string, you will treat this block of memory as an array of chars, so the pointer to the first memory address in the block will be a pointer to a char (the first one). More on reddit.com
🌐 r/learnprogramming
20
5
July 29, 2013
🌐
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...
🌐
Code Quoi
codequoi.com › en › malloc-allocating-memory-in-c
Malloc: Allocating Memory in C - codequoi
And for the students of 42, it is mandatory. #include <stdlib.h> int main(void) { char *ptr; ptr = malloc(sizeof *ptr * 25 + 1); if (!ptr) return (-1); free(ptr); return (0); } Of course, to free an array of strings, we must free each individual allocated string before freeing the array itself.
🌐
NG Emu
ngemu.com › home › forums › general discussion › web development / programming
C: Initializing an array using malloc | Next Generation Emulation
Edit: ermmm, except calloc which returns zeroed Memory *cough* *cough* First you have to allocate the Memory required: char *array = malloc( size * sizeof(char)); Then you can use memset to set a region of bytes to a certain value.
Top answer
1 of 5
48

Declaring Static Character Arrays (strings)

When you know (or have a reasonable idea how large your array needs to be, you can simply declare an array of sufficient size to handle your input (i.e. if you names are no longer than 25 characters, then you could safely declare name[26]. For strings, you always need at minimum the number of chars to store + 1 (for the null-terminating character).

If there may be a few characters more than 25, there's nothing wrong with declaring your array few bytes longer than needed to protect against accidental writing beyond the end of the array. Say name[32].

Let's declare an array of 5-characters below and look at how the information is stored in memory.

char name[5] = {0}; /* always initialize your arrays */

The above declaration creates an array of 5-contiguous bytes on the stack for your use. e.g., you can visualize the 5-bytes of memory initialized to zero as follows:

        +---+---+---+---+---+
 name   | 0 | 0 | 0 | 0 | 0 |
        +---+---+---+---+---+
          \
           'name' holds the starting address for
            the block of memory that is the array
            (i.e. the address of the first element
             like: 0x7fff050bf3d0)

Note: when using name to hold a 'character string', the actual string can be no longer than 4 chars because you must end a sting with a null-terminating character, which is the null-character '\0' (or simply numeric 0, both are equivalent)

To store information in name, you can either do it by assigning characters one-at-a-time:

name[0] = 'J';
name[1] = 'o';
name[2] = 'h';
name[3] = 'n';
name[4] =  0;   /* null-terminate. note: this was already done by initialization */

In memory you now have:

        +---+---+---+---+---+
 name   | J | o | h | n | 0 |    /* you actually have the ASCII value for */
        +---+---+---+---+---+    /* each letter stored in the elements    */

Of course, nobody assigns one character at a time in this manner. You options are many, using one of the functions provided by C, e.g. strcpy, strncpy, memcpy, or by reading information from a file stream, or file descriptor with fgets, getline, or by using a simple loop and index variable to do the assignment, or by using one of the string formatting functions, e.g. sprintf, etc... For example you can accomplish the same thing with any of the following:

/* direct copy */
strcpy (name, "John");
strncpy (name, "John", 5);
memcpy (name, "John", sizeof "John");  /* include copy of the terminating char */

/* read from stdin into name */
printf ("Please enter a name (4 char max): ");
scanf ("%[^\n]%*c", name);

Note: above with strncpy, if you had NOT initialized all element to 0 (the last of which will serve as your null-terminating character, and then used strncpy (name, "John", 4); you would need to manually terminate the string with name[4] = 0;, otherwise you would not have a valid string (you would have an unterminated array of chars which would lead to undefined behavior if you used name where a string was expected.)

If you do not explicitly understand this STOP, go read and understand what a null-terminated string is and how it differs from an array of characters. Seriously, stop now and go learn, it is that fundamental to C. (if it doesn't end with a null-terminating character - it isn't a c-string.

What if I don't know how many characters I need to store?

Dynamic Allocations of Character Strings

When you do not know how many characters you need to store (or generally how many of whatever data type), the normal approach is to declare a pointer to type, and then allocate a reasonably anticipated amount of memory (just based on your best understanding of what you are dealing with), and then reallocate to add additional memory as required. There is no magic to it, it is just a different way of telling the compiler how to manage the memory. Just remember, when you allocate the memory, you own it. You are responsible for (1) preserving a pointer to the beginning address of the memory block (so it can be freed later); and (2) freeing the memory when you are done with it.

A simple example will help. Most of the memory allocation/free functions are declared in stdlib.h.

char *name = NULL;  /* declare a pointer, and initialize to NULL */

name = malloc (5 * sizeof *name); /* allocate a 5-byte block of memory for name */

if (!name) {    /* validate memory was allocated -- every time */
    fputs ("error: name allocation failed, exiting.", stderr);
    exit (EXIT_FAILURE);
}

/* Now use name, just as you would the statically declared name above */
strncpy (name, "John", 5);

printf (" name contains: %s\n", name);

free (name);    /* free memory when no longer needed.
                   (if reusing name, set 'name = NULL;') 
                 */

Note: malloc does NOT initialize the contents of the memory it allocates. If you want to initialize your new block of memory with zero (as we did with the static array), then use calloc instead of malloc. You can also use malloc and then call memset as well.

What happens if I allocate memory, then need More?

As mentioned above discussing dynamic memory, the general scheme is to allocate a reasonable anticipated amount, then realloc as required. You use realloc to reallocate the original block of memory created by malloc. realloc essentially creates a new block of memory, copies the memory from your old block to the new, and then frees the old block of memory. Since the old block of memory is freed, you want to use a temporary pointer for reallocation. If reallocation fails, you still have your original block of memory available to you.

You are free to add as little or as much memory as you like at any call to realloc. The standard scheme usually seen is to start with some initial allocation, then reallocate twice that amount each time you run out. (the means you need to keep track of how much memory is currently allocated).

To sew this up, let's end with a simple example that simply reads a string of any length as the first argument to the program (use "quotes" if your string contains whitespace). It will then allocates space to hold the string, then reallocate to append more text to the end of the original string. Finally it will free all memory in use before exit:

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

int main (int argc, char **argv) {

    if (argc < 2) { /* validate input */
        fprintf (stderr, "error: insufficient input.  usage: %s \"name\"\n",
                 argv[0]);
        return 1;
    }

    size_t len = strlen (argv[1]);  /* length of input  */
    size_t sz_mem = len + 1;        /* memory required  */

    char *name = malloc (sz_mem * sizeof *name);  /* allocate memory for name */

    if (!name) {    /* validate memory created successfully or throw error */
        fputs ("error: name allocation failed, exiting.", stderr);
        return 1;
    }

    printf ("\n allocated %zu bytes of memory for 'name'\n", sz_mem);
    memset (name, 0, sz_mem); /* initialize memory to zero (optional) */

    strncpy (name, argv[1], sz_mem);  /* copy the null-terminator as well */
    printf (" name: '%s' (begins at address: %p)\n", name, name);

    /* realloc - make name twice as big */
    void *tmp = realloc (name, 2 * sz_mem);  /* use a temporary pointer */
    if (!tmp) {                              /* check realloc succeeded */
        fprintf (stderr, "error: virtual memory exhausted, realloc 'name'\n");
        return 1;
    }
    memset (tmp + sz_mem, 0, sz_mem * sizeof *name); /* zero new memory */
    name = tmp;         /* assign new block to name       */
    sz_mem += sz_mem;   /* update current allocation size */

    printf (" reallocated 'name' to %zu bytes\n", sz_mem);
    strncat (name, " reallocated", sizeof " reallocated");

    printf ("\n final name : '%s'\n\n", name);

    free (name);

    return 0;
}

Use/Output

$ ./bin/arraybasics "John Q. Public"

 allocated 15 bytes of memory for 'name'
 name: 'John Q. Public' (begins at address: 0xf17010)
 reallocated 'name' to 30 bytes

 final name : 'John Q. Public reallocated'

Memory Check

When you dynamically allocate memory, it is up to you to validate you are using the memory correctly and that you track and free all the memory you allocate. Use a memory error checker like valgrind to veryify your memory use is correct. (there is no excuse not to, it is dead-bang-simple to do) Just type valgrind yourprogramexe

$ valgrind ./bin/arraybasics "John Q. Public"
==19613== Memcheck, a memory error detector
==19613== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==19613== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==19613== Command: ./bin/arraybasics John\ Q.\ Public
==19613==

 allocated 15 bytes of memory for 'name'
 name: 'John Q. Public' (begins at address: 0x51e0040)
 reallocated 'name' to 30 bytes

 final name : 'John Q. Public reallocated'

==19613==
==19613== HEAP SUMMARY:
==19613==     in use at exit: 0 bytes in 0 blocks
==19613==   total heap usage: 2 allocs, 2 frees, 45 bytes allocated
==19613==
==19613== All heap blocks were freed -- no leaks are possible
==19613==
==19613== For counts of detected and suppressed errors, rerun with: -v
==19613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

In the output, the following lines are of particular significance:

==19613== HEAP SUMMARY:
==19613==     in use at exit: 0 bytes in 0 blocks
==19613==   total heap usage: 2 allocs, 2 frees, 45 bytes allocated

This tells you that all memory allocated during your program has been properly freed. (make sure you close all open file streams, they are dynamically allocated as well).

Of equal importance is the ERROR SUMMARY:

==19613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

There are no errors in the memory use. If you attempt to read, write or free memory from a location outside your block, or from an unitialized location or that would leave other memory unreachable, that information will show as an error.

(the suppressed: 2 from 2 just relate to additional debug libraries not present on my system)

This ended up longer than intended, but if it helps, it was worth it. Good luck.

2 of 5
5

How can I announce the array and then define it's size?

Don't; 'announce' it when you know what size it needs to be. You can't use it before then anyway.

In C99 and later, you can define variables when needed — anywhere in a statement block. You can also use VLAs (variable-length arrays) where the size is not known until runtime. Don't create enormous arrays as VLAs (e.g. 1 MiB or more — but tune the limit to suit your machine and prejudices); use dynamic memory allocation after all.

If you're stuck with the archaic C89/C90 standard, then you can only define variables at the start of a block, and arrays have sizes known at compile time, so you have to use dynamic memory allocation — malloc(), free() etc.

🌐
Reddit
reddit.com › r/c_programming › freeing a char array
r/C_Programming on Reddit: Freeing a char array
January 24, 2024 -

Hello,

I am just brushing up on pointers in preparation for a C unit I will be doing.

For this script

#include <stdio.h>
#include <stdlib.h>
int main(void) {
char (* ptr)[10] = malloc(sizeof(char) * 10);
for(int i = 0; i < 8; i++) {
(*ptr)[i] = 'h';
}
*ptr[9] = '\0';
//free(ptr);   //-------------THIS LINE
printf("%s\n",*ptr);
return 0;
}

What is the difference between 1. free(*ptr) and 2.free(ptr)?

2. Frees the ARRAY that ptr is pointing to

  1. Frees the first element in the array

Is there any difference?

By the way I know that "printf("%s\n",*ptr);" accesses an invalid pointer.

I just used it to notice the printed strings is different whether I free 1 or 2.

Thanks

Find elsewhere
🌐
Wikibooks
en.wikibooks.org › wiki › A_Little_C_Primer › C_Dynamic_Memory_Allocation_&_Deallocation
A Little C Primer/C Dynamic Memory Allocation & Deallocation - Wikibooks, open books for an open world
September 10, 2008 - /*malloc.c */ #include <stdio.h> #include <stdlib.h> /*For "malloc", "exit" functions. */ int main() { char *p; /*Pointer to array. */ unsigned count; /*Size of array. */ puts( "Size of array?" ); scanf( "%d", &count ); /*Get size in bytes. */ p = malloc( (size_t)count ); /*Allocate array.
🌐
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.
🌐
Reddit
reddit.com › r/learnprogramming › [c] storing strings using an array of char pointers and malloc.
r/learnprogramming on Reddit: [C] Storing strings using an array of char pointers and malloc.
July 29, 2013 -

I've been given the task of reading words into an array and then running insertion sort on them. The way it has been set out to do this is by using an array of char pointers and then assigning memory to each index in order to store a string. The code for that is already in place. But I just don't understand how using malloc makes space for a sting within a char? I'm honestly not even sure if what I just wrote makes sense. Pointers are frying my brain. Any help would be much appreciated. I've done a fair bit of Java before if that helps any explaination .

🌐
Cprogramming
cboard.cprogramming.com › c-programming › 159741-setting-character-malloced-char-array.html
Setting character in malloc'ed char array
#include <stdio.h> #include <stdlib.h> int main (int argc, char const* argv[]) { char str_one[4092] = "This is string number one"; char * str_two = "This is string number two"; char * str_three; str_three = (char *) malloc(4092); str_three = "This is the third string"; str_one[5] = 'X'; printf("%s\n", str_one); str_two++; *str_two = 'X'; // segfaults here str_two--; printf("%s\n", str_two); str_three++; *str_three = 'X'; // segfaults here str_three--; printf("%s\n", str_three); return 0; }
🌐
George Washington University
www2.seas.gwu.edu › ~simhaweb › C › modules › module3 › module3.html
Module 3: Pointers, strings, arrays, malloc
p = (int*) malloc (sizeof(int)); An easy way to remember this is: "the cast type is the same as the argument to ... It looks more complicated with 2D arrays, as we will see, but the essence is the same. After the pointer has a value, we can actually print the address: #include <stdio.h> #include ...
🌐
Eskimo
eskimo.com › ~scs › cclass › notes › sx11a.html
11.1 Allocating Memory with malloc
A ``byte'' in C is, by definition, an amount of storage suitable for storing one character, so the above invocation of malloc gives us exactly as many chars as we ask for. We could illustrate the resulting pointer like this: The 100 bytes of memory (not all of which are shown) pointed to by line are those allocated by malloc.
🌐
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 { int* indices; char* values; size_t size; size_t capacity; } SparseCharArray; SparseCharArray* create_sparse_char_array(size_t initial_capacity) { SparseCharArray* arr = malloc(sizeof(SparseCharArray)); arr->indices = malloc(initial_capacity * sizeof(int)); arr->values = malloc(initial_capacity * sizeof(char)); arr->size = 0; arr->capacity = initial_capacity; return arr; } Advanced memory handling requires deep understanding ·
Top answer
1 of 1
4

Here are some things that may help you improve your code.

Fix the bug

Once memory is freed, it should not be referenced again. Unfortunately, your code allocates memory and then frees it and then returns a pointer to the freed memory. That's a serious bug! To fix it, simply omit the free within the function and make sure the caller calls free instead. Alternatively, you could avoid all of that by reversing the passed string in place.

Use the required #includes

The code uses strlen which means that it should #include <string.h> and malloc and free which means that it should #include <stdlib.h>. It was not difficult to infer, but it helps reviewers if the code is complete.

Use const where practical

In your revere_string routine, the string passed into the function is not and should not be altered. You should indicate that fact by declaring it like this:

char* reverse_string(const char* string)

Check for NULL pointers

The code must avoid dereferencing a NULL pointer if the call to malloc fails. The only indication that it has failed is if malloc returns NULL; if it does, it would probably make most sense to immediately return that NULL pointer.

Learn to use pointers instead of indexing

Using pointers effectively is an important C programming skill. This code could be made much simpler by doing an in-place reversal of the passed string and by using pointers:

char* reverse_string(char* string) {
    if (string == NULL) 
        return string;
    char *fwd = string;
    char *rev = &string[strlen(string)-1];

    while (rev > fwd) {
        char tmp = *rev;
        *rev-- = *fwd;
        *fwd++ = tmp;
    }
    return string;
}
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-create-a-dynamic-array-of-strings-in-c
How to Create a Dynamic Array of Strings in C? - GeeksforGeeks
July 23, 2025 - We create an array of pointers to characters (i.e. strings) and then store the address of this array in the double-pointer to characters. Each of the pointer to the character is again allocated memory based on the size of the string it is storing.
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Dynamically Allocate Memory For An Array Of Chars - Programming - Arduino Forum
December 29, 2022 - I'm trying to create dynamic array of strings, but obviously I'm missing something... This does not compile: char **AOC; AOC = malloc(20 * sizeof(char *)); AOC[0] = malloc(20 * sizeof(char)); with this error: AOC = ma…
🌐
Williams College
cs.williams.edu › ~freund › cs010 › notes › lecture05.html
Strings & Introduction to Dynamic Memory Management
If we don't know how big we want the array initially, we could do the following: char *school; ... school = (char *)malloc (strlen ("Williams") + 1); strcpy (school, "Williams");
🌐
Swarthmore College
cs.swarthmore.edu › ~newhall › unixhelp › C_arrays.html
Arrays in C
Dynamically allocated arrays are allocated on the heap at run time. The heap space can be assigned to global or local pointer variables that store the address of the allocated heap space (point to the first bucket). To dynamically allocate space, use calls to malloc passing in the total number of bytes to allocate (always use the sizeof to get the size of a specific type).