0

I am trying to make a linked list implementation in C, I then decided to implement the same logic to create a 'string', essentially the same linked list with more functions, mainly to create the linked list object from an input string. The code works perfectly well when given a small input string like 35 characters, but crashes at the first time malloc runs when the input string is bigger. Now I have tried to run this code on a different machine and it works perfectly with any size string(below 1000 smth characters), so I suspect there is a problem with my machine here are the functions at cause:

struct Map
{
char val;
struct Map *next;
};


void makeString(struct Map **head, char *needStr){
int i = 0;
while (needStr[i] != '\0'){
    insert(head, needStr[i]);
    i++;
}
}

void insert(struct Map **head, char value){
printf("%c", value);
if ((*head) == NULL)
{
    (*head) = (struct Map *)malloc(sizeof(struct Map));
    (*head)->val = value;
    (*head)->next = NULL;
}
else
{
    struct Map *cur = *head;
    while (cur->next != NULL)
    {
        cur = cur->next;
    }

    struct Map *New = (struct Map *)malloc(sizeof(struct Map));
    New->val = value;
    New->next = NULL;
    cur->next = New;
}

}

int main()
{
struct Map *list = NULL;
char *a = (char*) malloc(sizeof(char)); 
scanf("%[^\n]",a); 
makeString(&string, a);
}

To provide a more visible understanding of the problem, here is an example:

Input:

Hello, how are you?

Output:

Hello, how are you?

code works, runs all other functions called in main.

Input: "******************************************************************************************************************************************************"

Output: "*"

vscode points out an error in malloc inside the insert function, and it happens on the first iteration.

huntrese
  • 25
  • 5

1 Answers1

3

The problem is here:

malloc(sizeof(char));

You allocate space for one single character. If you read a string, that can only fit the string terminator.

You need to make sure there's enough space to fit all of the input, plus the string terminator.

I recommend you create an actual array, with a fixed size, and then use fgets to read your line of input instead. That makes it easier to limit the input:

char a[256];
fgets(a, sizeof a, stdin);

If you're worried about the newline that fgets leave in the buffer, see this old answer.

And remember to check if fgets succeeds or not.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Hello, thanks for the help, this indeed makes the program work, however I was mainly trying to understand why the previous one did not, especially the part where it worked on a different computer. – huntrese Feb 02 '23 at 13:04
  • 1
    @huntrese If you only have a single character allocated, and string with a size larger than zero will go out of bounds of the allocated memory. Going out of bounds leads to *undefined behavior*. Unfortunately, if you have undefined behavior it's often really hard to predict what's going to happen. If you're *unlucky* it will all seem to work, and if you're lucky it will crash. – Some programmer dude Feb 02 '23 at 13:09