1

This is a program that's supposed to read inputs, a number 'n' and a character, and then duplicate this character n times. It works perfectly fine, but when I enter a large number, 8+ for example, it duplicates perfectly but then adds garbage values to the end. I can't get why it does that since I used malloc and I have exactly n blocks saved for me in the memory.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* create_string (char ch, int n);
void main ()
{
    int n;
    char ch;
    printf("Enter number for duplicates: ");
    scanf("%d",&n);
    printf("Enter a letter: ");
    scanf(" %c", &ch);
    printf("The letter '%c' duplicated %d times is: ",ch,n);
    char* ptr=create_string(ch,n);
    printf("%s",ptr);
}
char* create_string (char ch, int n)
{
    char* dup=(char*)malloc(n*sizeof(char));
    int i;
    for (i=0; i<n; i++)
    {
        dup[i]=ch;
    }
    return dup;
}

Test run: Test run.

Mureinik
  • 297,002
  • 52
  • 306
  • 350

2 Answers2

3

Strings in C are as simple as null-terminated character sequences. That means whenever you create a string by hand, you must always append a '\0' at the end so other functions like printf know where it ends:

char* create_string (char ch, int n)
{
    char* dup = malloc((n+1) * sizeof(char));
    int i;
    for (i=0; i<n; i++)
    {
        dup[i]=ch;
    }

    // This is important
    dup[n] = '\0';

    return dup;
}

Another subtle thing to notice is that because you need to store that terminating null character, you also need to reserve the space for it. So the malloc line is changed into:

malloc((n+1)*sizeof(char))
//     ^^^^^ it's no longer 'n'

On a side note, you don't need to cast the returned pointer of malloc.

iBug
  • 35,554
  • 7
  • 89
  • 134
1

Strings in C are char arrays where the character \0 denotes the end of the string. Since you aren't explicitly adding it, printf just prints values from memory until it happens to run in to a terminating character (i.e., this is undefined-behavior). Instead, you should explicitly add this character to your result string:

char* create_string (char ch, int n)
{
    char* dup = (char*) malloc((n + 1) * sizeof(char));
    /* Added 1 for the '\0' char ---^ */

    int i;
    for (i = 0; i < n; i++)
    {
        dup[i]=ch;
    }

    /* Set the terminating char */
    dup[n] = '\0';

    return dup;
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350