user3221699 user3221699 - 3 months ago 18
C Question

Storing double the user entry in a dynamic pointer in C

I am learning pointers and doing an exercise where I'm dynamically creating a pointer and accepting input from the user and then storing the double the user entry to the dynamically created pointer in the heap and printing out the dynamically created heap to the console. The problem I am having is, it is not printing double the users entry, I have debugged it and it looks like the t variable is not saving double the user entry and i'm not sure how to resolve this.

I have posted my code below and would greatly appreciate any tips or hits that would help me solve the issue I am having.

The current output is:
Say something: hey
Size of char: 8
Size of s: 8
Size of t: 8
Doubling copy...
Original: hey
Double copy: hey
Counter: 8


The desired output is:

Say something: hey
Size of char: 8
Size of s: 8
Size of t: 8
Doubling copy...
Original: hey
Double copy: heyhey (I would like this line to print double the word the user entered as input)
Counter: 8


code:

#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
int scale_value = 2;
int counter = 0;

printf("Say something: ");
char* s = GetString();

if (s == NULL)
{
return 1;
}

string t = malloc((strlen(s) * scale_value + 1)* sizeof(char));

if (t == NULL)
{
free(s);
return 1;
}

printf("Size of char: %lu\n", sizeof(char*));
printf("Size of s: %lu\n", sizeof(s));
printf("Size of t: %lu\n", sizeof(t));

for(int j = 0; j < scale_value; j++)
{
for (int i = 0, n = strlen(s); i<=n; i++)
{
t[counter] = s[i];
counter++;
}
}

printf("Doubling copy...\n");

if (strlen(t)>0)
{
printf("Original: %s\n", s);
printf("Double copy: %s\n", t);
printf("Counter: %d\n", counter);
}
}

Answer

It is because you copied the terminating null-character scale_value times instead of once and the first terminating null-character will terminate the string. This issue will not only terminate the string too early but also cause out-of-range access (buffer overrun).

Try this instead of the copying part:

for(int j = 0; j < scale_value; j++)
{
    /* change <= to < to exclude the terminating null-character from what is copied */
    for (int i = 0, n = strlen(s); i<n; i++)
    {
            t[counter] = s[i];
            counter++;
    }
}
/* terminate the string */
t[counter++] = '\0';

Also note that %lu is not correct format specifier to print what is returned from sizeof, which has type size_t. Using %zu is correct. Using incorrect format specifier will invoke undefined behavior.