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
  • 134,614
  • 21
  • 188
  • 335
rustyMagnet
  • 2,781
  • 1
  • 22
  • 35

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
  • 63,700
  • 7
  • 105
  • 170
  • 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
  • 17,836
  • 5
  • 33
  • 54