efrat
efrat

Reputation: 13

calloc issue on second time - on C

bellow is the code:

from some reason the calloc inside the while loop, is failing on the second iteration. it looks the heap is corupted (not sure) but not clear the root cause. please also take a look on the comment added there. appriciate fast response.

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include<stdio.h>
#include <stdlib.h>

struct User_
{
    char* id;
    char* firstName;
    char* lastName;
    int age;
    char gender[2];
    char* userName;
    char* password;
    char* description;
    char hobbies[2];
}typedef User;


void replaceEnterInString(int lengthString, char* string, int  maxChars);




int main()
    {
        char str1[500] = "012345678;danny;cohen;22;M;danny1993;123;1,2,4,8;Nice person";
        char str2[500] = "223325222;or;dan;25;M;ordan10;1234;3,5,6,7;Singer and dancer";


    int j = 0;
    char *token = NULL, arrangingHobbies;
    int lengthStr, tempAge, hobby[4], i;

    while(j<2)
    {

        User* newUser = NULL;

here it pass on first time but fail on second time. but only when adding the code that map the token to the newUser. without the mapping - do manage to calloc the user again and again as much as needed

error code: Critical error detected c0000374 - TEST.exe has triggered a breakpoint.

        newUser = (User*)calloc(1, sizeof(User));
        if (newUser == NULL)
        {
            printf("error");
            exit(1);
        }

        //start map string to user
        if (j == 0)
        {
            token = strtok(str1, ";");
            printf("%s", str1);
        }
        else {
            token = strtok(str2, ";");
            printf("%s", str2);
        }

        //Input ID
        newUser->id = (char*)calloc(10, sizeof(char));
        if (newUser->id == NULL)
        {
            printf("error");
            exit(1);
        }
        strcpy(newUser->id, token);

        //Input first name
        token = strtok(NULL, ";");
        lengthStr = strlen(token);
        newUser->firstName = (char*)calloc((lengthStr + 1), sizeof(char));
        if (newUser->firstName == NULL)
        {
            printf("error");
            exit(1);
        }
        strcpy(newUser->firstName, token);

        //Input last name
        token = strtok(NULL, ",;");
        lengthStr = strlen(token);
        newUser->lastName = (char*)calloc((lengthStr + 1), sizeof(char));
        if (newUser->lastName == NULL)
        {
            printf("error");
            exit(1);
        }
        strcpy(newUser->lastName, token);

        //Input Age
        token = strtok(NULL, ",;");
        tempAge = atoi(token);
        newUser->age = tempAge;

        //Input gender
        token = strtok(NULL, ",;");
        newUser->gender[0] = token[0];


        //Input User Name
        token = strtok(NULL, ",;");
        lengthStr = strlen(token);
        newUser->userName = (char*)calloc((lengthStr), sizeof(char));
        if (newUser->userName == NULL)
        {
            printf("error");
            exit(1);
        }
        strcpy(newUser->userName, token);

        //Input password
        token = strtok(NULL, ",;");
        lengthStr = strlen(token);
        newUser->password = (char*)calloc((lengthStr), sizeof(char));
        if (newUser->password == NULL)
        {
            printf("error");
            exit(1);
        }
        strcpy(newUser->password, token);

        //Input hobbies
        newUser->hobbies[0] = 0;
        for (i = 0; i < 4; ++i)
        {
            token = strtok(NULL, ",;");
            tempAge = atoi(token);
            arrangingHobbies = 1;
            arrangingHobbies <<= (tempAge - 1);
            newUser->hobbies[0] |= arrangingHobbies;
        }

        //Input description
        token = strtok(NULL, ",;");
        newUser->description = (char*)calloc((lengthStr), sizeof(char));
        if (newUser->description == NULL)
        {
            printf("error");
            exit(1);
        }
        replaceEnterInString(strlen(token), token, 300);
        strcpy(newUser->description, token);

        j++;
    }

}

void replaceEnterInString(int lengthString, char* string, int  maxChars)
{
    if (lengthString < maxChars)
    {
        //remove the /n
        string[lengthString - 1] = '\0';
    }
}

Upvotes: 0

Views: 272

Answers (1)

Stephan Lechner
Stephan Lechner

Reputation: 35154

Maybe there are other issues as well, yet the following code leads to undefined behaviour for sure:

lengthStr = strlen(token);
newUser->userName = (char*)calloc((lengthStr), sizeof(char));
...
strcpy(newUser->userName, token);

In previous similar statements, you correctly wrote ... = (char*)calloc((lengthStr+1), sizeof(char));.

BTW: In C, you usually don't cast the results of malloc, sizeof(char) is always 1 by definition, and there is no need for setting memory to 0 using calloc if you fill the memory with a subsequent strcpy anyway. So you should write...

lengthStr = strlen(token);
newUser->userName = malloc(lengthStr+1);
...
strcpy(newUser->userName, token);

Look through your code for similar issues, please.

Upvotes: 5

Related Questions