Thread: Assertion Failure Help

  1. #1
    Registered User
    Join Date
    Jan 2017
    Posts
    19

    Assertion Failure Help

    Hi,

    I'm trying to tokenize a string that has been read from a file but I keep getting an assertion failure :
    Expression: string != nullptr
    For information on how your program can cause an assertion
    failure, see the Visual C++ documentation on asserts.


    Here is the code from the function that I'm having an issue with. The assertion failure occurs inside the while() loop - Also, the program isn't close to being finished but this is preventing me from moving forward

    Code:
     .
    void SetProfile(char**ReadData, Profile *User, DayStats *Node, int DaysOnDiet)
    {
     char *Container;
     int k = 1;
    
     User->Name = strtok(ReadData[0], ", ");
     Container = strtok(NULL, ",");
     User->Height = atoi(Container);
     Container = strtok(NULL, ",");
     User->StartingWeight = atof(Container);
     Container = strtok(NULL, ",");
     User->DesiredWeightLoss = atof(Container);
     Container = strtok(NULL,",");
     User->DesiredDays = atoi(Container);
     Container = strtok(NULL, ",");
     User->Age = atoi(Container);
     Container = strtok(NULL, ",");
     User->StartingBMR = atof(Container);
     Container = strtok(NULL, ",");
     User->Day = atoi(Container);
    
     if (DaysOnDiet > 1)
     {
      while (ReadData[k] != NULL)
      {
       
       Container = strtok(ReadData[k], ",");
       Node->Steps = atoi(Container);
       Container = strtok(NULL, ",");
       Node->BMR = atof(Container);
       Container = strtok(NULL, ",");
       Node->Weight = atof(Container);
       Container = strtok(NULL, ",");
       Node->TotalCaloriesBurned = atof(Container);
       Container = strtok(NULL, ",");
       Node->CaloriesBurnedFromWorkout = atof(Container);
       Container = strtok(NULL, ",");
       Node->CaloriesConsumed = atof(Container);
       Container = strtok(NULL, ",");
       Node->CaloricDeficit = atof(Container);
       Container = strtok(NULL, ",");
       Node->Day = atoi(Container);
       k++;
      }
     }
    }
    .

    The entire code -

    Main:
    Code:
    .
    
    #include "header.h"
    int main(void)
    {
     FILE *infile = fopen("profile.txt", "r");
     int DataInFile = FALSE, FileSize = 0, MenuOption = 0, DaysOnDiet, CheckMenu[3] = { 0 }, k = 0, SaveNode = FALSE;
     char *ProfileData[365] = {NULL};
     Profile *UserProfile = (Profile*)malloc(sizeof(Profile));
     DayStats *Node = (DayStats*)malloc(sizeof(DayStats));
     Node->Next = NULL;
     Head = NULL;
     Tail = NULL;
     if (infile == NULL)
     {
      perror("\nAn error occurred while opening the file\n\n");
      exit(1);
     }
     else
     {   /*fscanf returns a negative value if there is no data in the file.If profile/file is empty, get user input for starting body parameters, if else - display main menu*/
      
      char *ReadFirstLineOfProfile[100];
      double CheckIfProfileIsEmpty = fscanf(infile, "%s", ReadFirstLineOfProfile);
      if (CheckIfProfileIsEmpty < 0)
      {
       GetProfileInfo(UserProfile);
       ProfileToFile(UserProfile);
       fclose(infile);
      }
      do {
       DaysOnDiet = ReadProfileData(ProfileData, infile);
       SetProfile(ProfileData, UserProfile, Node, DaysOnDiet);
       MenuOption = MainMenu();//Returns an integer value from user input(menu option)
       DayNode(ProfileData, DaysOnDiet, UserProfile, MenuOption, SaveNode,Node);
       switch (MenuOption)
       {
       case 1:CheckMenu[0] = 1;
        break;
       case 2:CheckMenu[1] = 1;
        break;
       case 3:CheckMenu[2] = 1;
        break;
       }
       for (int i = 0; i < 3; i++)
       {
        if (CheckMenu[i] == 1)
         SaveNode = TRUE;
       }
       if (MenuOption == 6)
       {
        DayStats *temp = (DayStats*)malloc(sizeof(DayStats));
        if (Tail == NULL)
        {
         Tail = Head = Node;
         Tail->Next = Head;
         Head->Next = NULL;
        }
        else
        {
         temp->Next = Tail;
         Tail = temp;
        }
        free(temp);
        AppendFromTail(Tail);
        SaveNode = FALSE;
        for (int i = 0; i < 3; i++)
         CheckMenu[i] = 0;
       }
      } while (MenuOption != 7);
     }
    
    
     return 0;
    }
    .

    definitions:
    Code:
    .
    void GetProfileInfo(Profile *User)
    {
     int MALE = 1, FEMALE = 2;
     printf("\n\n\t\t\t\tWeight Loss Tracker...\n");
     /****************REMEMBER TO ADD SLEEP FUNCTION HERE!!*/
     CLEAR;
     printf("\n\n\t\t\tFirst, I will need some information from you so that I can generate your profile...\n");
     
     CLEAR;
     User->Name = (char*)malloc(100);
     /*Enter User Name and measurables*/
     printf("\n\nEnter your name:");
     scanf("%[^\n]%*c", User->Name);
     CLEAR;
     printf("\n%s, enter your Height(inches):", User->Name);
     scanf("%d", &User->Height);
     CLEAR;
     printf("\nEnter your weight(pounds):");
     scanf("%lf", &User->StartingWeight);
     CLEAR;
     printf("\nEnter your age:");
     scanf("%d", &User->Age);
     CLEAR;
     printf("\nHow much weight(pounds) do you want to lose?:");
     scanf("%lf", &User->DesiredWeightLoss);
     CLEAR;
     printf("\In how many days do you want to meat your goal?:");
     scanf("%d", &User->DesiredDays);
     CLEAR;
     printf("\nWhich gender are you?\n1.Male\n2.Female\n");
     int Gender;
     scanf("%d", &Gender);
     if (Gender == MALE)
      User->StartingBMR = (66.47) + (13.7 * (User->StartingWeight)) + (5 * (User->Height * 2.54)) - (6.8 * (User->Age));
     else if(Gender == FEMALE)
      User->StartingBMR = (655.1) + (9.6 * (User->StartingWeight)) + (1.8 * (User->Height * 2.54)) - (4.7 * (User->Age));
     CLEAR;
     return;
    }
    void ProfileToFile(Profile *user)
    {
     /*Pre condition: the profile.txt file is empty*/
     /*Post condition: profile.txt is opened for writing.The first line of the profile.txt file contains data pertaining to the initial  body parameters. Commas are used as data delimeters.
     Profile.txt is closed for writing at the conclusion of this function*/
     FILE *outfile = fopen("profile.txt", "w");
     fprintf(outfile,"%s,%d,%.2lf,%.2lf,%d,%d,%.2lf,1\n", user->Name, user->Height, user->StartingWeight, user->DesiredWeightLoss, user->DesiredDays, user->Age, user->StartingBMR);
     fclose(outfile);
    }
    int MainMenu()
    {
     int MenuOption;
     printf("\n\t\t\t\t    Weight Manager\n");
     printf("\n1.Log Workout\n2.Log Steps\n3.Log Calories\n4.View Stats\n5.Edit Profile\n6.Next Day\n7.Exit\n");
     scanf("%d", &MenuOption);
     return MenuOption;
    }
    int ReadProfileData(char **ProfileData, FILE *infile)
    {
     /*Pre condition: infile contains data that is not being used by the program*/
     /*Post Condition: All data contained in profile.txt is stored in the string array 'ProfileData' - 
     where each ProfileData[index] contains a string of characters that are grouped by the line position
     of the profile.txt file*/
     int k = 0;
     infile = fopen("profile.txt", "r");
     if (infile == NULL)//if profile is empty print an error message
     {
      perror("\nProfile Data Does Not exist\n");
      exit(1);
     }
     else
     {   /*Reserve 200 bytes of character data in memory for ProfileData[k]*/
      ProfileData[k] = (char*)malloc(200);
      /*Read contiguous lines from infile and store
      the data as strings in the string array 'ProfileData' until the end of file is reached. The first
      200 characters will be read into the array*/
      while (fgets(ProfileData[k], 200, infile) != NULL)
      {
       k++;
       ProfileData[k] = (char*)malloc(200);
      }
     }
     fclose(infile);
     return k;//Returning this value gives us the number of days the diet has been active.The number of days is equal to the number of lines in the profile.txt file
    }
    void DayNode(char **ProfileData, int DayOfDiet, Profile *Pro, int MenuOption, int SaveNode, DayStats *Node)
    {
     
     int IntData;
     double DoubData;
     /*Set all struct variables to 0.This is done in case the user chooses to not insert a value for the below(3) Node variables*/
     if (SaveNode == 0)
     {
      Node->Steps = 0;
      Node->CaloriesConsumed = 0;
      Node->CaloriesBurnedFromWorkout = 0;
     }
     Node->Day = DayOfDiet;
     if (MenuOption == 2)
     {
      CLEAR;
      printf("\n\nEnter the number of steps taken today:");
      scanf("%d", &IntData);
      Node->Steps += IntData;
      CLEAR;
     }
     if (MenuOption == 3)
     {
      CLEAR;
      printf("\n\nEnter the amount of calories consumed today:");
      scanf("%lf", &DoubData);
      Node->CaloriesConsumed += DoubData;
      CLEAR;
     }
     if (MenuOption == 1)
     {
      CLEAR;
      printf("\n\nEnter the amount of calories burned from working out:");
      scanf("%lf", &DoubData);
      Node->CaloriesBurnedFromWorkout += DoubData;
      CLEAR;
     }
     
     if (DayOfDiet == 1)
     {
      double CalsPerStep = (0.57 * Pro->StartingWeight)/2200;
      double TotalStepCals = Node->Steps * CalsPerStep;
      Node->Weight = Pro->StartingWeight - ((Pro->StartingBMR - Node->CaloriesConsumed + Node->CaloriesBurnedFromWorkout + TotalStepCals)/3500);
      Node->BMR = (66.47) + (13.7 * (Node->Weight)) + (5 * (Pro->Height * 2.54)) - (6.8 * (Pro->Age));
      Node->TotalCaloriesBurned = Pro->StartingBMR + Node->CaloriesBurnedFromWorkout + TotalStepCals;
            
     }
     else if (DayOfDiet > 1)
     {
      double CalsPerStep = (0.57 * Tail->Weight);
      double TotalStepCals = Node->Steps * CalsPerStep;
      Node->Weight = Tail->Weight - ((Tail->BMR - Node->CaloriesConsumed + Node->CaloriesBurnedFromWorkout + TotalStepCals) / 3500);
      Node->BMR = (66.47) + (13.7 * (Node->Weight)) + (5 * (Pro->Height * 2.54)) - (6.8 * (Pro->Age));
      Node->TotalCaloriesBurned = Tail->BMR + Node->CaloriesBurnedFromWorkout + TotalStepCals;
     }
     Node->CaloricDeficit = Node->TotalCaloriesBurned - Node->CaloriesConsumed;
     return;
    }
    void SetProfile(char**ReadData, Profile *User, DayStats *Node, int DaysOnDiet)
    {
     char *Container;
     int k = 1;
    
     User->Name = strtok(ReadData[0], ", ");
     Container = strtok(NULL, ",");
     User->Height = atoi(Container);
     Container = strtok(NULL, ",");
     User->StartingWeight = atof(Container);
     Container = strtok(NULL, ",");
     User->DesiredWeightLoss = atof(Container);
     Container = strtok(NULL,",");
     User->DesiredDays = atoi(Container);
     Container = strtok(NULL, ",");
     User->Age = atoi(Container);
     Container = strtok(NULL, ",");
     User->StartingBMR = atof(Container);
     Container = strtok(NULL, ",");
     User->Day = atoi(Container);
     if (DaysOnDiet > 1)
     {
      while (ReadData[k] != NULL)
      {
       
       Container = strtok(ReadData[k], ",");
       Node->Steps = atoi(Container);
       Container = strtok(NULL, ",");
       Node->BMR = atof(Container);
       Container = strtok(NULL, ",");
       Node->Weight = atof(Container);
       Container = strtok(NULL, ",");
       Node->TotalCaloriesBurned = atof(Container);
       Container = strtok(NULL, ",");
       Node->CaloriesBurnedFromWorkout = atof(Container);
       Container = strtok(NULL, ",");
       Node->CaloriesConsumed = atof(Container);
       Container = strtok(NULL, ",");
       Node->CaloricDeficit = atof(Container);
       Container = strtok(NULL, ",");
       Node->Day = atoi(Container);
       k++;
      }
     }
    }
    void AppendFromTail(DayStats *Tail)
    {
     FILE *infile = fopen("profile.txt", "a+");
     fprintf(infile, "%d,%.2lf,%.2lf,%.2lf,%.2lf,%.2lf,%.2lf,%d\n", Tail->Steps, Tail->BMR, Tail->Weight, Tail->TotalCaloriesBurned, Tail->CaloriesBurnedFromWorkout, Tail->CaloriesConsumed, Tail->CaloricDeficit,Tail->Day);
     fclose(infile);
    }
    .

    Header file:
    Code:
    .
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #define CLEAR system("cls");
    typedef enum
    {
     FALSE, TRUE 
    };
    typedef struct profile
    {
     char *Name;
     double StartingWeight;
     double CurrentWeight;
     double DesiredWeightLoss;
     double StartingBMR;
     int Height;
     int DesiredDays;
     int Age;
     int Day;
    }Profile;
    typedef struct daystats
    {   /*Weight is calculated in pounds. Height is calculated in inches*/
     int Day;
     int Steps;
     double BMR;
     double Weight;
     double TotalCaloriesBurned;
     double CaloriesBurnedFromWorkout;
     double CaloriesConsumed;
     double CaloricDeficit;
     struct daystats *Next;
    }DayStats;
    DayStats *Head, *Tail;
    void GetProfileInfo(Profile *User);
    void ProfileToFile(Profile *user);
    int MainMenu();
    int ReadProfileData(char **ProfileData, FILE *infile);
    void DayNode(char **ProfileData, int DayOfDiet, Profile *Pro, int MenuOption, int SaveNode, DayStats *Node);
    void SetProfile(char**ReadData, Profile *User, DayStats *Node, int DaysOnDiet);
    void AppendFromTail(DayStats *Tail);
    .

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You run the code in the debugger, and it will point you at a line of code.

    My guess is one of those atoi() calls is being passed NULL where a valid pointer was expected.
    Hence
    " Expression: string != nullptr"

    Probably, your file doesn't have as many , separated fields as you imagine.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jan 2017
    Posts
    19
    Quote Originally Posted by Salem View Post
    You run the code in the debugger, and it will point you at a line of code.

    My guess is one of those atoi() calls is being passed NULL where a valid pointer was expected.
    Hence
    " Expression: string != nullptr"

    Probably, your file doesn't have as many , separated fields as you imagine.
    Thanks for the reply.
    My debugger points to the following line:

    Node->BMR = atof(Container);

    However, the string that was converted from a file - that's being tokenized in the while loop- looks like this:

    0,4233.14,251.79,4249.77,0.00,0.00,4249.77,1

  4. #4
    Registered User
    Join Date
    Jan 2017
    Posts
    19
    Ah! Just caught it! Needed to add another delamination character at the end of these strings.
    ~Thanks for the help

  5. #5
    Registered User
    Join Date
    Jan 2017
    Posts
    19
    Quote Originally Posted by ntantar View Post
    Ah! Just caught it! Needed to add another delamination character at the end of these strings.
    ~Thanks for the help
    Never mind - did not fix the issue :/

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    This stood out to me almost immediately:


    Code:
        if (Tail == NULL)
        {
         Tail = Head = Node;
         Tail->Next = Head;
         Head->Next = NULL;
        }
        else
        {
         temp->Next = Tail;
         Tail = temp;
        }
        free(temp);
        AppendFromTail(Tail);

    If the "else" branch is taken, Tail and temp point to the same object, so you can't free temp without also invalidating Tail. That means you can't use Tail after you free temp.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assertion Failure
    By jamez05 in forum C Programming
    Replies: 5
    Last Post: 07-21-2006, 12:10 PM
  2. Assertion Failure
    By osal in forum C Programming
    Replies: 11
    Last Post: 06-03-2004, 10:25 PM
  3. Assertion Failure
    By drdroid in forum Game Programming
    Replies: 9
    Last Post: 01-04-2003, 07:02 PM
  4. MFC Assertion Failure
    By maxthecat in forum Windows Programming
    Replies: 5
    Last Post: 08-01-2002, 09:58 AM
  5. Assertion Failure
    By JagWire in forum C Programming
    Replies: 7
    Last Post: 07-24-2002, 11:45 AM

Tags for this Thread