I'm trying to get a hold of dynamic memory allocation and I just want my program to get a string and the max number of characters that should be printed from the string from the user, then just output the string up to the number of characters I allocated with calloc
. When I run the program, it completely disregards the limit I set for it using calloc()
and just prints out the whole string.
I tried using malloc
but had the same results. Also, I dereferenced text when I first tried printing out the inputted text but it caused the program to stop after you entered the string you wanted printed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int max;
char *text = NULL;
printf("\n\n");
printf("Please enter the limit for the string as a positive integer: \n");
scanf("%d", &max);
text = (char *)calloc(max, sizeof(char));
if (text != NULL)
{
printf("Please enter the string you want printed: \n");
scanf(" "); //read in next character so it pauses
gets(text);
printf("Inputted text is : %s\n", text);
}
free(text);
text = NULL;
return 0;
}
Yes, I know, I get the warning that gets
is unsafe but I was watching from a tutorial and the instructor's version built and ran fine. Even if I use scanf
to read in a string into text, the result it the same.
Revised code using fgets()
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int max;
char *text = NULL;
printf("\n\n");
printf("Please enter the limit for the string as a positive integer: \n");
scanf("%d", &max);
text = (char *)calloc(max, sizeof(char));
if (fgets(text, max, stdin))
{
printf("Please enter the string you want printed: \n");
fgets(text, max, stdin);
text[strcspn(text, "\n")] = '\0';
printf("Inputted text is : %s\n", text);
}
free(text);
text = NULL;
return 0;
}
I changed my code to use fgets
instead and made some corrections. It returns 1 less character than the "max" the user inputs. Also, does using fgets
mean I don't need to bother with calloc
?
When you allocate memory and assign it to a pointer, there is no way to deduce the size of the memory from the pointer in hand. So gets
has no chance (and will therefore not check) if it will exceed the amount of memory you reserved. BTW: gets
is not part of C standard any more (since C11). Use fgets
instead and pass your max
as argument:
if (fgets(text, max, stdin)) {
// something successfully read in
text[strcspn(text, "\n")] = '\0';
}
Note that fgets
, in contrast to gets
, preserves any entered new line and keeps it at the end of text
. To get rid of this, you can use text[strcspn(text, "\n")] = '\0'
, which will let the string end at the new line character (if any).