3

I followed How to memset char array with null terminating character? to add a null terminator when using the C memset api.

The code worked; I no longer got odd in-memory chars added to the end of my malloc'd char array, due to the null terminator.

/* memset does not add a null terminator */
static void yd_vanilla_stars(size_t *number_of_chars, char *chars_to_pad)
{
    memset(chars_to_pad, 0, *number_of_chars+1);
    memset(chars_to_pad,'*',*number_of_chars);
}

Is there a more elegant way of achieving the same?

M.M
  • 138,810
  • 21
  • 208
  • 365
rustyMagnet
  • 3,479
  • 1
  • 31
  • 41

2 Answers2

8

You could simply do this:

memset(chars_to_pad, '*', *number_of_chars);
chars_to_pad[*number_of_chars] = '\0';

Also, why number_of_chars is a pointer?

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • I was trying to follow a pattern of Pass By Reference in my code. Would you pass by value for a size_t or int? – rustyMagnet Feb 10 '18 at 20:06
  • 1
    @rustyMagnet For such small types passing by value shouldn't be slower, and is definitely more readable. Related: https://stackoverflow.com/a/270435/2752075 (It discusses passing by value vs passing by const reference in C++; passing by pointer should work more or less like passing by reference) – HolyBlackCat Feb 10 '18 at 20:12
2

The question suggests that chars_to_pad points to memory allocated using malloc(). Another alternative is to use calloc() instead. This function automatically zero-initializes the allocated memory, so there is no need to zero the allocation in a separate step.

An example might look like this:

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

int main(void)
{
    size_t arr_sz = 11;
    char *arr = calloc(arr_sz, sizeof *arr);
    memset(arr, '*', arr_sz - 1);

    puts(arr);

    return 0;
}

Program output:

**********
ad absurdum
  • 19,498
  • 5
  • 37
  • 60