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.

Answer from Dmitri on Stack Overflow
🌐
Reddit
reddit.com › r/learnprogramming › [c] how do i convert a buffer back to a string (opposite of snprintf)
r/learnprogramming on Reddit: [c] How do I convert a buffer back to a string (opposite of snprintf)
November 15, 2014 -

I'm a beginner and lost between all these print functions. I already managed to copy a 4byte string to a 4 byte buffer using snprintf(). Is there a similar function to unpack it back to a string on the other side?

How input buffer works Jun 10, 2025
r/C_Programming
last yr.
Problem with sprintf(buffer, "string: %f", float_num) Sep 16, 2023
r/C_Programming
3y ago
How can I convert an integer to a string? Oct 16, 2021
r/C_Programming
4y ago
Converting char to string : r/cpp_questions Oct 16, 2022
r/cpp_questions
3y ago
How to do strings properly? May 5, 2026
r/cprogramming
5mo ago
More results from reddit.com
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.

Discussions

c - Converting buffer to array of strings - Stack Overflow
I downloaded text from the edit field to the buffer and I want to convert it to an array of strings. Every string is ending with %. void Converter(HWND hwnd) { int Length = GetWindowTextLength(... More on stackoverflow.com
🌐 stackoverflow.com
c - copying strings into a buffer - Stack Overflow
Second, it is illegal to convert a char** to a const char** for reasons explained here. ... which you are expecting to fail when you've reached the empty string at the end of the animals array, is wrong. That statement is actually checking if the pointer which points to the string is NULL, ... More on stackoverflow.com
🌐 stackoverflow.com
How do I convert a buffer to a binary string in c++? - Stack Overflow
I am trying to convert an arbitrary buffer to a string of its binary representation. I was looking at some code from here: http://snippets.dzone.com/posts/show/2076 in order to get started. I re... More on stackoverflow.com
🌐 stackoverflow.com
June 23, 2011
How do you convert a byte array to a hexadecimal string in C? - Stack Overflow
With hex string in a character buffer, user/caller can use its own macro/function to display or log it to any place it wants (e.g. to a file). This function also allows caller to control number of (hex) bytes to put in each line. Copy/** * @fn * get_hex * * @brief * Converts a char into bunary ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
C For Dummies
c-for-dummies.com › blog
Outputting an Unterminated Buffer | C For Dummies Blog
The printf() format string uses the * variable width placeholder to set the string’s output width, using the size variable in the argument list. The characters are output, but they remain in the buffer without being converted into a string.
🌐
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 stringbuffer_clear(buffer); bool is_empty = stringbuffer_is_empty(buffer); printf("Is Empty: %d\n", is_empty); // once done, free the buffer stringbuffer_release(buffer); } /* main */
Author: sagiegurari
🌐
Bun
bun.sh › binary data › convert a buffer to a string
Convert a Buffer to a string - Bun
August 4, 2026 - The Buffer class provides a .toString() method that converts a Buffer to a string.
🌐
Bun
bun.com › guides › binary data › buffer to string
Convert a Buffer to a string | Bun Guides
The Buffer class provides a .toString() method that converts a Buffer to a string.
🌐
DEV Community
dev.to › idnkxchange › string-buffer-in-c-3g3g
String Buffer in C - DEV Community
December 3, 2020 - Sets the length of this String buffer. ... Returns a new character sequence that is a subsequence of this sequence. ... Returns a new String that contains a subsequence of characters currently contained in this StringBuffer. The substring begins at the specified index and extends to the end of the StringBuffer. ... Returns a new String that contains a subsequence of characters currently contained in this StringBuffer. ... Converts to a string representing the data in this string buffer.
Find elsewhere
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.

🌐
GitHub
github.com › alcover › buf
GitHub - alcover/buf: C string buffer library
February 19, 2021 - Making *Buf a contiguous chunk of memory. And you still get your good old C-string through the buf_data() accessor. The example folder implements the 'forum'. It reads rows from a mock db, and renders them to a page of limited size.
Author: alcover
🌐
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 3
2

The array bitstring has what is known as automatic duration, which means that it springs into existence when the function is called and disappears when the function returns.

Therefore, the pointer that this version of getBufferAsBinaryString returns is to an array which no longer exists by the time the caller receives the pointer. (Remember that the statement return bitstring; returns a pointer to the first character in bitstring; by the "equivalence of arrays and pointers," the mention of the array bitstring in this context is equivalent to &bitstring[0].)

When the caller tries to use the pointer, the string created by getBufferAsBinaryString might still be there, or the memory might have been re-used by some other function. Therefore, this version of getBufferAsBinaryString is not adequate and not acceptable. Functions must never return pointers to local, automatic-duration arrays.

Since the problem with returning a pointer to a local array is that the array has automatic duration by default, the simplest fix to the above non-functional version of getBufferAsBinaryString is to declare the array static, instead:

char *getBufferAsBinaryString(void *in)
{
    int pos=0;
    char result;
    static char bitstring[256];
    memset(bitstring, 0, 256);
    unsigned int *input= (unsigned int *)in;
    for(int i=31;i>=0;i--)
    {
            if (((*input >> i) & 1)) result = '1';
            else result = '0';
            bitstring[pos] = result;
            if ((i>0) && ((i)%4)==0)
            {
                    pos++;
                    bitstring[pos] = ' ';
            }
            pos++;
    }
    return bitstring;
}

Now, the bitstring array does not disappear when getBufferAsBinaryString returns, so the pointer is still valid by the time the caller uses it.

Returning a pointer to a static array is a practical and popular solution to the problem of "returning" an array, but it has one drawback. Each time you call the function, it re-uses the same array and returns the same pointer. Therefore, when you call the function a second time, whatever information it "returned" to you last time will be overwritten. (More precisely, the information, that the function returned a pointer to, will be overwritten.)

Although the static return array technique will work, the caller has to be a little bit careful, and must never expect the return pointer from one call to the function to be usable after a later call to the function

But you still have a different problem with passing in void * which I did not cover, in addition not passing in the size of your buffer. Since you shouldn't assume that your array ends in the \0, you should also pass in the size of your buffer.

2 of 3
1

Ignoring the other issues with memory and safety, you are not returning a valid null terminated string. Nor do you pass in the size of the input buffer, so you really just print out the 32-bit bit representation of the first 32-bits of the input buffer.

So, in addition to passing in a char buffer to write to or simply returning a std::string, you should also pass in the size of the input buffer and loop over that as well.

Top answer
1 of 16
123
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);

For a more generic way:

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) printf(":");
    printf("%02X", buf[i]);
}
printf("\n");

To concatenate to a string, there are a few ways you can do this. I'd probably keep a pointer to the end of the string and use sprintf. You should also keep track of the size of the array to make sure it doesn't get larger than the space allocated:

int i;
char* buf2 = stringbuf;
char* endofbuf = stringbuf + sizeof(stringbuf);
for (i = 0; i < x; i++)
{
    /* i use 5 here since we are going to add at most 
       3 chars, need a space for the end '\n' and need
       a null terminator */
    if (buf2 + 5 < endofbuf)
    {
        if (i > 0)
        {
            buf2 += sprintf(buf2, ":");
        }
        buf2 += sprintf(buf2, "%02X", buf[i]);
    }
}
buf2 += sprintf(buf2, "\n");
2 of 16
47

For completude, you can also easily do it without calling any heavy library function (no snprintf, no strcat, not even memcpy). It can be useful, say if you are programming some microcontroller or OS kernel where libc is not available.

Nothing really fancy you can find similar code around if you google for it. Really it's not much more complicated than calling snprintf and much faster.

#include <stdio.h>

int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    int i = 0;
    for(; i < sizeof(buf)-1; ++i){
        *pout++ = hex[(*pin>>4)&0xF];
        *pout++ = hex[(*pin++)&0xF];
        *pout++ = ':';
    }
    *pout++ = hex[(*pin>>4)&0xF];
    *pout++ = hex[(*pin)&0xF];
    *pout = 0;

    printf("%s\n", str);
}

Here is another slightly shorter version. It merely avoid intermediate index variable i and duplicating laste case code (but the terminating character is written two times).

#include <stdio.h>
int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    for(; pin < buf+sizeof(buf); pout+=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
    }
    pout[-1] = 0;

    printf("%s\n", str);
}

Below is yet another version to answer to a comment saying I used a "trick" to know the size of the input buffer. Actually it's not a trick but a necessary input knowledge (you need to know the size of the data that you are converting). I made this clearer by extracting the conversion code to a separate function. I also added boundary check code for target buffer, which is not really necessary if we know what we are doing.

#include <stdio.h>

void tohex(unsigned char * in, size_t insz, char * out, size_t outsz)
{
    unsigned char * pin = in;
    const char * hex = "0123456789ABCDEF";
    char * pout = out;
    for(; pin < in+insz; pout +=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
        if (pout + 3 - out > outsz){
            /* Better to truncate output string than overflow buffer */
            /* it would be still better to either return a status */
            /* or ensure the target buffer is large enough and it never happen */
            break;
        }
    }
    pout[-1] = 0;
}

int main(){
    enum {insz = 4, outsz = 3*insz};
    unsigned char buf[] = {0, 1, 10, 11};
    char str[outsz];
    tohex(buf, insz, str, outsz);
    printf("%s\n", str);
}
🌐
Arduino Forum
forum.arduino.cc › projects › programming
byte buffer to String object - Programming - Arduino Forum
October 22, 2020 - My question related to generic pattern: get string from a buffer. I have bytes/ascii chars buffer. This buffer does NOT have string terminator. I want to convert this whole buffer to String object. This is minimum. Maximum: specify offset and size string in the buffer.
🌐
Bun
bun.com › guides › binary › buffer-to-string.md
Convert a Buffer to a string
The Buffer class provides a .toString() method that converts a Buffer to a string.
Top answer
1 of 4
6

In addition to what the other answers say and I generally agree with:

Don't call strlen more than once. That's just a waste. Count the length of orig_str and append_str once at the beginning of the function and store them away in const variables. That will also make your initial check whether append_str is empty look cleaner:

const size_t append_len = strlen(append_str);
if (!append_len)
    return orig_str;
const size_t orig_len = strlen(orig_str);

Moving the strlen(orig_str) above the conditional would look cleaner in my eyes but it might be a pessimization if append_str is often empty.

Of course, the most efficient way would be if you could pass orig_len as an additional input parameter. Or you could use a

struct string_buffer
{
  size_t length;
  size_t capacity;
  char * data;
};

that encapsulates all the required info and change your function's signature to

ssize_t
append_string(struct string_buffer * buffer, const char * appendix);

where the function could return the number of bytes successfully appended or –1 on error.

My second remark would be that you are growing your buffer by a constant amount each time you reallocate. It should really grow exponentially unless you really know that linear growth will be preferable in your specific use-case, which I find hard to imagine how that could be.

Concerning your comments: there is no NULL byte. NULL is a macro constant for the null pointer. The null byte is abbreviated as NUL in the ASCII character set. I would also find it helpful to have your function's semantics exactly documented in a comment. For example, should the user free the buffer if it fails and returns NULL? Will the existing data be modified in that case? I can try answering those questions by reading your implementation but that doesn't allow me to distinguish a bug in your code from a different valid design decision.

2 of 4
4
  • strcat(orig_str, append_str) looks cleaner than a strcpy/strlen combo.

  • memset is pointless. You need only 1 terminating zero, and it is taken care of by string routines.

  • The responsibilities of if (req_space > *orig_str_size) and a corresponding else clauses overlap. The only task of the if clause should be string reallocation. Copying needs to be performed in any case. Consider instead

    if (req_space > *orig_str_size) {
        allocate = ...;
        char *new_str = realloc(orig_str, allocate);
        if (new_str == NULL) {
            handle_error;
        }
        *orig_str_size = allocate;
        orig_str = new_str;
    }
    strcat(orig_str, append_str);
    
  • fprintf doesn't belong to a such low level routine. Returning an error condition is enough. It is up to the caller to print or not to print.

Top answer
1 of 2
2

You must check the return value of scanf. If you don't, you run into an endless loop when reaching the end of the file. And, even worse, you invoke undefined behavior.

You could split the loop into two: first, skip all whitespace, then read the remaining text.

int dscan(char *buf, int bufsize) {
    int ch;

    while ((ch = getc()) != EOF && ch != '\n' && isspace(ch)) {
        continue;
    }

    int idx = 0;
    while (ch != EOF && ch != '\n' && idx < bufsize) {
        buf[idx++] = ch;
        ch = getc();
    }

    if (ch == '\n' && idx < bufsize) {
        buf[idx++] = '\n';
    }
    if (idx < bufsize) {
        buf[idx++] = '\0';
    }

    return idx;
}

I changed several things:

  • EOF is handled correctly. On EOF, the string is returned, properly null-terminated. (This was not the case in your code.)
  • Leading whitespace does not count towards the buffer, it is simply ignored, like you said in your description. Your code counted it.
  • Each call to an I/O function is checked for an error result.
  • It's easy to strip the newline character from the string by removing the corresponding if sentence. Depending on whether the calling code needs this or not.
  • If dscan(buf, size) < size, the buffer is a string, i.e. it is properly null-terminated.
  • Calling isspace does not invoke undefined behavior. In your code, if I enter a negative char, the behavior is undefined. See the <ctype.h> documentation.
2 of 2
2

what can be improved?

The contract "scan input to string buffer" and "a function that reads standard input, ignores initial whitespace and fills the buffer with that data." lacks directions on how to handle many cases.

  1. Code appears to be reading until end-of-line, yet that is not specified. Even if so, with ignoring leading white-space, it makes sense to also ignore trailing-white-space including the potential '\n'.

  2. Appending a '\0' to insure a string does meet the title requirement. Should anything special happen if a null character '\0' is read?

  3. Buffer size too small? What to do with extra characters? Consume them, leave them for the next I/O functions?

  4. How to handle an immediate end-of-file? Or an end-of-file after some characters?

  5. How to handle a rare input error?

  6. How to handle pathological input like where == NULL, size <= 0?

  7. Array sizes exceeding INT_MAX?

Perhaps some of these corner case result in a "don't care" or UB as the contract does not specify a behavior. Yet consider a production task with the loose requirements.

Customers expect code to behave well is "all" situations. Although every conceivable issue is a worthy goal and not truly attainable, as an implementor, code should be resilient to many situations. These include ones that are not considered by the customer, yet reasonably possible. For corner cases that significantly reduce performance, greater coding goal detail is needed.


@Roland Illig addresses some coding weakness in OP's code. Some additional ideas:

// Add functional comment
// Return 0 when no data read or error

// int dscan(char *where, int size) {
// Use size_t in and out to convey buffer size and usage
size_t dscan(char *where, size_t size) {

  // Assess input values
  if (where == NULL || size == 0) {
    return 0;
  }

  // decrement to save space for a \0
  size--;

  // Read the entire line
  // getchar() better than scanf("%c", &c)
  // It gets an unsigned char value and indicates end-of-file/error
  int c;
  size_t i = 0;
  size_t non_white_space_next = 0;
  while ((c = fgetc(stdin)) != EOF && c != '\n') {
    if (i < size) {
      if (isspace(c)) {
        if (i == 0) continue;
        where[i++] = c;
      } else {
        where[i++] = c;
        non_white_space_next = i;
      }
    } else {
      ; // What to do with too many characters?
      // For now, code will ignore them
      // Yet code should convey that buffer was too small.
    }
  }

  // If code is to ignore trailing space
  i = non_white_space_next;

  // Always append a null character
  where[i] = '\0';

  // Typically if no characters are read or an error occur,
  // code should return 0 to indicate
  if (c == EOF && (ferror(stdin) || i == 0)) {
    return 0;
  }
  return i+1;
}
Top answer
1 of 5
5

Assuming that

  • by “string” you mean a null-terminated string as is normally meant in C;
  • you haven't yet allocated memory in data;
  • you already know that s <= x

First you need to allocate memory in data. Don't forget the room for the 0 byte at the end of the string.

data = malloc(s+1);
if (data == NULL) {
    ... /*out-of-memory handler*/
}

Assuming malloc succeeds, you can now copy the bytes.

EDIT:

The best function for the job, as pointed out by caf, is strncat. (It's fully portable, being part of C89.) It appends to the destination string, so arrange for the destination to be an empty string beforehand:

*(char*)data = 0;
strncat(data, buf, s);

Other inferior possibilities, kept here to serve as examples of related functions:

  • If you have strlcpy (which is not standard C but is common on modern Unix systems; there are public domain implementations floating around):

    strlcpy(data, buf, s+1);
    
  • If you know that there are at least s characters in the source string, you can use memcpy:

    memcpy(data, buf, s);
    

    ((char*)data)[s+1] = 0;

  • Otherwise you can compute the length of the source string first:

    size_t bytes_to_copy = strlen(buf);
    if (bytes_to_copy > s) bytes_to_copy = s;
    memcpy(data, buf, bytes_to_copy);
    ((char*)data)[s+1] = 0;
    
  • Or you can use strncpy, though it's inefficient if the actual length of the source string is much smaller than s:

    strncpy(data, buf, s);
    ((char*)data)[s+1] = 0;
    
2 of 5
3

If data is not allocated:

char buf[] = "mybuffer";
void *data = malloc(strlen(buf)+1);
strcpy((char*)data,buf);

Actually if data is really to be defined you can also do

char buf[] = "mybuffer";
void *data= (void*)strdup(buf);