The array animals is an array of pointers. It is not an array of buffers of some size. Therefor, if you do

sizeof(*animals)

You will get the sizeof of the first element of that array. Equivalent to

sizeof(char*)

Because your array stores pointers. So, in the line that reads

char *output[sizeof(*animals)];

You allocate 4 or 8 pointers in one array (depends on how wide a pointer on your platform is. Usually it's either 4 or 8). But that's of course not senseful! What you wanted to do is create an array of pointers of the same size as animals. You will have to first get the total size of the animals array, and then divide by the size of one element

char *output[sizeof(animals)/sizeof(*animals)];

Now, that is what you want. But the pointers will yet have indeterminate values... Next you pass the array using *&animals (same for the other). Why that? You can pass animals directly. Taking its address and then dereference is the same as doing nothing in the first place.

Then in the function you call, you copy the strings pointed to by elements in animal to some indeterminate destination (remember the elements of the output array - the pointers - have yet indeterminate values. We have not assigned them yet!). You first have to allocate the right amount of memory and make the elements point to that.

while(*animals) {
        // now after this line, the pointer points to something sensible
        *output = malloc(sizeof("new animal ") + strlen(*animals));
        sprintf(*output, "new animal %s", *animals); 
        output++; // no need to dereference the result
        animals++; // don't forget to increment animals too!
}

Addition, about the sizeof above

There's one important thing you have to be sure about. It's the way we calculate the size. Whatever you do, make sure you always have enough room for your string! A C string consists of characters and a terminating null character, which marks the end of the string. So, *output should point to a buffer that is at least as large so that it contains space for "new animal " and *animals. The first contains 11 characters. The second depends on what we actually copy over - its length is what strlen returns. So, in total we need

12 + strlen(*animals)

space for all characters including the terminating null. Now it's not good style to hardcode that number into your code. The prefix could change and you could forget to update the number or miscount about one or two characters. That is why we use sizeof, which we provide with the string literal we want to have prepended. Recall that a sizeof expression evaluates to the size of its operand. You use it in main to get the total size of your array before. Now you use it for the string literal. All string literals are arrays of characters. string literals consist of the characters you type in addition to the null character. So, the following condition holds, because strlen counts the length of a C string, and does not include the terminating null character to its length

// "abc" would have the type char[4] (array of 4 characters)
sizeof "..." == strlen("...") + 1

We don't have to divide by the size of one element, because the sizeof char is one anyway, so it won't make a difference. Why do we use sizeof instead of strlen? Because it already accounts for the terminating null character, and it evaluates at compile time. The compiler can literally substitute the size that the sizeof expression returns.

Answer from Johannes Schaub - litb on Stack Overflow
Top answer
1 of 5
7

The array animals is an array of pointers. It is not an array of buffers of some size. Therefor, if you do

sizeof(*animals)

You will get the sizeof of the first element of that array. Equivalent to

sizeof(char*)

Because your array stores pointers. So, in the line that reads

char *output[sizeof(*animals)];

You allocate 4 or 8 pointers in one array (depends on how wide a pointer on your platform is. Usually it's either 4 or 8). But that's of course not senseful! What you wanted to do is create an array of pointers of the same size as animals. You will have to first get the total size of the animals array, and then divide by the size of one element

char *output[sizeof(animals)/sizeof(*animals)];

Now, that is what you want. But the pointers will yet have indeterminate values... Next you pass the array using *&animals (same for the other). Why that? You can pass animals directly. Taking its address and then dereference is the same as doing nothing in the first place.

Then in the function you call, you copy the strings pointed to by elements in animal to some indeterminate destination (remember the elements of the output array - the pointers - have yet indeterminate values. We have not assigned them yet!). You first have to allocate the right amount of memory and make the elements point to that.

while(*animals) {
        // now after this line, the pointer points to something sensible
        *output = malloc(sizeof("new animal ") + strlen(*animals));
        sprintf(*output, "new animal %s", *animals); 
        output++; // no need to dereference the result
        animals++; // don't forget to increment animals too!
}

Addition, about the sizeof above

There's one important thing you have to be sure about. It's the way we calculate the size. Whatever you do, make sure you always have enough room for your string! A C string consists of characters and a terminating null character, which marks the end of the string. So, *output should point to a buffer that is at least as large so that it contains space for "new animal " and *animals. The first contains 11 characters. The second depends on what we actually copy over - its length is what strlen returns. So, in total we need

12 + strlen(*animals)

space for all characters including the terminating null. Now it's not good style to hardcode that number into your code. The prefix could change and you could forget to update the number or miscount about one or two characters. That is why we use sizeof, which we provide with the string literal we want to have prepended. Recall that a sizeof expression evaluates to the size of its operand. You use it in main to get the total size of your array before. Now you use it for the string literal. All string literals are arrays of characters. string literals consist of the characters you type in addition to the null character. So, the following condition holds, because strlen counts the length of a C string, and does not include the terminating null character to its length

// "abc" would have the type char[4] (array of 4 characters)
sizeof "..." == strlen("...") + 1

We don't have to divide by the size of one element, because the sizeof char is one anyway, so it won't make a difference. Why do we use sizeof instead of strlen? Because it already accounts for the terminating null character, and it evaluates at compile time. The compiler can literally substitute the size that the sizeof expression returns.

2 of 5
2

You haven't allocated any space in your output array to put the copy into. You'll need to use malloc to allocate some space before using sprintf to copy into that buffer.

void p_init(const char **animals, char **output)
{
    while(*animals)
    {
        size_t stringSize = 42; /* Use strlen etc to calculate the size you need, and don't for get space for the NULL! */
        *output = (char *)malloc(stringSize);
        sprintf(*output, "new animal %s", *animals); 
        output++;
        animals++;
    }
}

Don't forget to call free() on that allocated memory when you are done with it.

🌐
Reddit
reddit.com › r/c_programming › safest way to copy a string?
r/C_Programming on Reddit: Safest way to copy a string?
May 7, 2023 -

I just fell foul of the fact that strncpy does not add an old terminator if the destination buffer is shorter than the source string. Is there a single function standard library replacement that I could drop in to the various places strncpy is used that would copy a null terminated string up to the length of the destination buffer, guaranteeing early (but correct) termination of the destination string, if the destination buffer is too short?

Edit:

  • Yes, I do need C-null terminated strings. This C API is called by something else that provides a buffer for me to copy into, with the expectation that it’s null terminated

Edit 2:

  • I know I can write a helper function that’s shared across relevant parts of the code, but I don’t want to do that because then each of those modules that need the function becomes coupled to a shared helper header file, which is fine in isolation but “oh I want to use this code in another project, better make sure I take all the misc dependencies” is best avoided. Necessary if necessary, but if possible using a standard function, even better.

Discussions

Copying string literals in C into an character array - Stack Overflow
I have a string literal: char *tmp = "xxxx"; I want to copy the string literal into an array. For example: how do I copy tmp into an char array[50]? and how to copy one string literal to another? More on stackoverflow.com
🌐 stackoverflow.com
C - copy buffer to string - is it even possible? - Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... is it possible to copy buffer to a string? More on stackoverflow.com
🌐 stackoverflow.com
loops - Copying characters from a source string to a buffer - C - Stack Overflow
I am currently working on a computer science project and have gotten it totally working bar a very specific case which I cannot seem to fix. The goal of the code is to write a function int tokenCop... More on stackoverflow.com
🌐 stackoverflow.com
printf - Copy a section of a string into buffer in C - Stack Overflow
It's ok to do, and a fairly common technique both for a compile-time allocation like there, or a run-time allocation. Do, however, use a #define instead of your magic 4, 2 and 32 numbers: #define BUFFER_LEN 32 #define SOURCE_SUBSTR_LEN 4 #define SOURCE_OFFSET 2 char buffer[BUFFER_LEN]; ... No, it simply calculates an address that is 2 elements from the start of the string... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Pixelbeat
pixelbeat.org › programming › gcc › string_buffers.html
The correct usage of string buffers in C
Often it may be simpler or more efficient to fall back to memcpy as was done in buffer_or_output() for example, where we're appending to a string in a large buffer. It's also worth noting how string buffers are allocated by the compiler. I.E. beware of sizeof on strings · char* string1="12345678"; char string2[]="12345678"; char string3[8]="12345678"; /* C99 supports excluding NUL, C++ does not.
Top answer
1 of 4
10

Use strcpy(), strncpy(), strlcpy() or memcpy(), according to your specific needs.

With the following variables:

const char *tmp = "xxxx";
char buffer[50];

You typically need to ensure your string will be null terminated after copying:

memset(buffer, 0, sizeof buffer);
strncpy(buffer, tmp, sizeof buffer - 1);

An alternative approach:

strncpy(buffer, tmp, sizeof buffer);
buffer[sizeof buffer - 1] = '\0';

Some systems also provide strlcpy() which handles the NUL byte correctly:

strlcpy(buffer, tmp, sizeof buffer);

You could naively implement strlcpy() yourself as follows:

size_t strlcpy(char *dest, const char *src, size_t n)
{
    size_t len = strlen(src);

    if (len < n)
        memcpy(dest, src, len + 1);
    else {
        memcpy(dest, src, n - 1);
        dest[n - 1] = '\0';
    }

    return len;
}

The above code also serves as an example for memcpy().

Finally, when you already know that the string will fit:

strcpy(buffer, tmp);
2 of 4
3

Use strcpy, it is pretty much well documented and easy to find:

const char* tmp = "xxxx";
// ...
char array[50];
// ...
strcpy(array, tmp);

But of course, you must make sure that the length of the string that you are copying is smaller than the size of the array. An alternative then is to use strncpy, which gives you an upper limit of the bytes being copied. Here's another example:

const char* tmp = "xxxx";
char array[50];
// ...
array[49] = '\0';
strncpy(array, tmp, 49); // copy a maximum of 49 characters

If the string is greater than 49, the array will still have a well-formed string, because it is null-terminated. Of course, it will only have the first 49 characters of the array.

Top answer
1 of 3
1

First, a C string is not just a char, but an array of char with the last element (or at least the last one that's counted as part of the string) set to the null character (numerically 0, also '\0' as a character constant).

Next, in the code you posted you probably meant char buffer[50] rather than char *buffer[50]... the version you have is an array of 50 char *s, but you need an array of 50 chars. After that's corrected, then...

Since fgets() always fills in a null char at the end of the string it read, buffer would already be a valid C string after you call fgets(). If you'd like to copy it to another string so you can reuse the buffer to read more input, you can use the usual string handling functions from <string.h>, such as strcpy(). Just make sure the string you copy it into is large enough to hold all the used characters plus a terminating null character.

This code copies the string into a newly malloc()ed string (error checking omitted):

char buffer[50];
char *str;
fgets(buffer,50,stdin);
str = malloc(strlen(buffer) + 1);
strcpy(str,buffer);

This code does the same, but copies to a char array on the stack (not malloc()ed):

char buffer[50];
char str[50];
fgets(buffer,50,stdin);
strcpy(str,buffer);

strlen() will tell you how many characters are used in the string, but doesn't count the terminating null (so you need to have one more character allocated than what strlen() returns). strcpy() will copy the characters and the null at the end from one string/buffer to another. It stops after the null, and doesn't know how much space you've allocated -- so you need to make sure it will find a null character before running out of space in the destination, or reaching the end of the source buffer. If in doubt, place a null at the end of the buffer yourself to make sure.

2 of 3
0

It should be char buffer[50]; and yes, you can then use strncpy (which does not care if it got a static or a heap allocated zone).

But I would recommend using getline in your case.

🌐
IBM
ibm.com › docs › en › zos › 2.4.0
memcpy() — Copy buffer
We cannot provide a description for this page right now
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › different-ways-to-copy-a-string-in-c-c
Different ways to copy a string in C/C++ - GeeksforGeeks
July 23, 2025 - We can use the inbuilt function strcpy() from <string.h> header file to copy one string to the other.
Find elsewhere
🌐
Vultr
docs.vultr.com › clang › standard-library › string-h › strcpy
C string.h strcpy() - Copy String Content | Vultr Docs
September 27, 2024 - The strcpy(destination, source); line copies the string from source to destination. The output is Copied String: Hello, World!, showing that the content was copied successfully. Be aware that not checking the size of the destination buffer can ...
🌐
Quora
quora.com › What-is-the-safest-way-to-copy-strings-in-C
What is the safest way to copy strings in C? - Quora
Answer (1 of 5): As you question is not clear I will provide for you possible ways available in that I think can be safe. 1. void *memcpy(void *dest, const void *src, size_t n): It copies n character from source to destination. [code]#include #include int main () { cons...
🌐
Linux Man Pages
linux.die.net › man › 3 › strcpy
strcpy(3): copy string - Linux man page
#include <string.h> char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n); The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the ...
🌐
Rip Tutorial
riptutorial.com › copying strings
C Language Tutorial => Copying strings
(Such quirky implementation is historical and was initially intended for handling UNIX file names) The only correct way to use it is to manually ensure null-termination: strncpy(b, a, sizeof(b)); /* the third parameter is destination buffer ...
🌐
GeeksforGeeks
geeksforgeeks.org › c language › strcpy-in-c
strcpy() in C - GeeksforGeeks
March 6, 2026 - The function copies the entire source string, including the null terminator, into the destination buffer. It does not perform bounds checking, meaning it will overwrite memory if the destination buffer is not large enough to hold the ...
🌐
Sternum IoT
sternumiot.com › home › strcpy and strncpy c functions – syntax, examples, and security best practices
strcpy and strncpy C Functions | Syntax, Examples & Security Best Practices | Sternum IoT
January 30, 2024 - The strcpy() function is a standard library function in the C programming language, designed to copy strings from one memory location to another. It is included in the string.h header file and stands for “string copy.” The primary objective ...
🌐
Quora
quora.com › How-do-I-copy-a-string-in-C
How to copy a string in C - Quora
Answer (1 of 2): Three major ways. 1. strncpy [code]char* src = "a const string to be copied"; char dest[28] = {0}; char *strncpy(char *dest, const char *src, size_t n); dest[n]= '\0'; // terminate manually [/code] 1. strncpy copies a char array src into another char array dest up to a given ...
🌐
GitHub
github.com › sagiegurari › c_string_buffer
GitHub - sagiegurari/c_string_buffer: A simple string buffer for C · GitHub
stringbuffer_shrink(buffer); // get a clone text value of the current buffer content char *text = stringbuffer_to_string(buffer); printf("The Text: %s\n", text); // we can clear the content we have so far and reuse the // string buffer instance ...
Starred by 6 users
Forked by 2 users
Languages   C 94.0% | CMake 4.8% | Shell 1.2%
🌐
Experts Exchange
experts-exchange.com › questions › 20569581 › i-want-to-copy-a-char-buffer-into-string.html
Solved: i want to copy a char buffer into string | Experts Exchange
April 1, 2003 - >> i have a char buffer defined for 100. >> the value in charbuff is to be copied in a string with the help of strcpy >> but i get an error saying parameter1 of strcpy argument is not char* You mean you are trying to place a char array into an std::string? If so, strcpy is not needed for this task.