I tried this method in C because I didn't want to predefine the size of the char * (like char[999]). My main purpose was to create a char * variable to hold a specific word (I dont know how it runs) when I use this code (I did not believed that would work properly while I was coding too) it creates one space of memory for a character. But when I try to print down it prints down the whole string and amazingly when I debug it the console just shows the first character of the string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int val;
char *name;
struct Node *next;
};
int main()
{
struct Node *list;
list = (struct Node *)malloc(sizeof(struct Node));
list->name = (char *)malloc(sizeof(char));
printf("Enter a string");
scanf("%s", list->name);
printf("%s", list->name);
return 0;
}
I think there is a memory leak or something. Because without any multiplier in the malloc() function I dont believe the compiler would allocate enough memory but I dont know how it saves the letters after the first one that I do not know where.
When you allocate memory for name with malloc(sizeof(char)), you're allocating exactly one byte of memory, which is enough space for exactly one character. In C, strings are null-terminated, meaning they end with a special null character ('\0'). So, technically, this allocation only has room for an empty string (just the null terminator) .
When you use scanf("%s", list->name) to read a string from the user, scanf does not know that you've only allocated space for one character. It will write the user's input into the memory starting at list->name, overrunning the allocated space if the user inputs anything at all as scanf() always adds a null teminator. This is known as a buffer overflow and is a common source of bugs and security vulnerabilities in C programs.
Despite the buffer overflow, you might find that your program seems to work correctly for small strings. This is because writing past the allocated memory may not immediately cause a crash; it overwrites some other part of your program's memory, which might not be used or checked immediately. However, this is unpredictable and unsafe. The behavior can change with different inputs, compiler optimizations, or even different runs of the same program.
As mention: " because of i didnt wanted to predefine the size of the char* (like char[999]) my main purpose was to create a char* variable to hold a specific word "
Maybe you could write this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buffer[1000];
scanf("%999s", buffer);
int len = strlen(buffer);
printf("%d\n", len);
struct Node *list;
list = (struct Node *)malloc(sizeof(struct Node));
list->name = (char *)malloc((len + 1) * sizeof(char));
strcpy(list->name, buffer);
printf("%s\n", list->name);
return 0;
}
I think it's impossible to predict in advance how many characters a user will type...
There is no standard way to achieve your goal with scanf() alone: scanf("%s", list->name) is inherently unsafe as scanf() will store all matching input to the destination array so any sufficiently long word entered by the user will cause a buffer overflow.
There are two possible solutions:
if you can assume that a maximum length, use a local array to store the input and allocate a copy of the string read:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int val;
char *name;
struct Node *next;
};
int main(void)
{
char buf[1000];
struct Node *list;
list = malloc(sizeof(struct Node));
if (list == NULL) {
fprintf(stderr, "cannot allocate memory\n");
return 1;
}
printf("Enter a string");
if (scanf("%999s", buf) != 1) {
fprintf(stderr, "invalid or missing input\n");
free(list);
return 1;
}
list->name = strdup(buf);
if (list->name == NULL) {
fprintf(stderr, "cannot duplicate string\n");
free(list);
return 1;
}
printf("%s\n", list->name);
free(list->name);
free(list);
return 0;
}
Alternately, you can use a function to read a word of arbitrary length, including 0 that scanf() cannot handle. This approach seems more in line with your goal to read a string from the user as opposed to a word parsed by %s:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int val;
char *name;
struct Node *next;
};
char *get_string(const char *prompt) {
size_t len = 0;
size_t size = 16;
char *buf = malloc(size);
int c;
if (!buf)
return NULL;
if (prompt) {
printf("%s: ", prompt);
fflush(stdout);
}
while ((c = getchar()) != EOF && c != '\n') {
if (len + 2 > size) {
size_t new_size = size + (size >> 1) + 8;
char *new_buf = realloc(buf, new_size);
if (new_buf == NULL) {
free(buf);
return NULL;
}
size = new_size;
buf = new_buf;
}
buf[len++] = c;
}
buf[len] = '\0';
return buf;
}
int main(void)
{
struct Node *list = malloc(sizeof(struct Node));
if (list == NULL) {
fprintf(stderr, "cannot allocate memory\n");
return 1;
}
list->val = 0;
list->next = NULL;
list->name = get_string("Enter a string");
if (list->name == NULL) {
fprintf(stderr, "cannot allocate memory\n");
free(list);
return 1;
}
printf("%s\n", list->name);
free(list->name);
free(list);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With