-2

So I am trying to open a file and parse a file in C++ (using initializeSimulation(). I can open the file successfully, but when I try to parse the file and store specific values from the file into my variables, I get the THREAD 1 error. The DataParser.cpp file is one I am required to use and cannot modify, I am to simply call it. I think the issue is with my function call to getData() (using pointers) but I cannot seem to figure out why. The way my variables are set up now is working weirdly for some reason, until i try to store m_sMaxVal. When I set them all up as pointers, I was getting a different error. I'm new to C++ but please let me know if you need any more information, and thanks in advance.

Simulation.cpp

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "Simulation.hpp"
#include "dDataParser.h"

Simulation::Simulation() {}
Simulation::~Simulation(){}

void Simulation::initializeSimulation() {

    char *fileName;
    char *m_sType;
    char m_sMaterial;
    int m_iID;
    char m_sUnits;
    double m_sMinVal;
    double *m_sMaxVal;


    cout << "Enter the name of the data file:" << endl;
    cin >> fileName ;
    //cout << fileName << "\n" ;

    parser = new EnviroSimDataParser(fileName);
    parser ->getSensorData(m_sType, &m_sMaterial, &m_iID, &m_sUnits, &m_sMinVal, m_sMaxVal);
}

DataParser.cpp

EnviroSimDataParser::EnviroSimDataParser(char *fileName)
{
char line[128];
strcpy(m_sFileName, fileName); 
inFile = new ifstream();
inFile->open(m_sFileName, fstream::in); // Open the data file
m_iNumSensors = 0;  // Number of sensors in the file
m_iNumDisplays = 0; // Number of display devices in the file
m_iNextSensor = 0;  // Next sensor number to read
m_iNextDisplay = 0; // Next display number to read

if(inFile->is_open())
{
    cout << "file opened successfully1 \n";
    // Count the number of sensors
    while(getNextLine(line, 127))
    {
        if(strcmp(line, "<SENSOR>") == 0)
            m_iNumSensors++;
        if(strcmp(line, "<DISPLAY_DEVICE>") == 0)
            m_iNumDisplays++;
    }

    inFile->close();
    cout << "file closed successfully1 \n";
}
else
{
    cout << "Failed to open file. Application terminated...\n";
    exit(0);
}
}
//-----

bool DataParser::getData(char *type, char *material, int *ID,
        char *units, double *minVal, double *maxVal)
{
    int sNum = 0;
    char line[128];

    // See if we have read all sensors
    if(m_iNextSensor >= m_iNumSensors) return false;

    // Reopen the file
    inFile = new ifstream();
    inFile->open(m_sFileName, fstream::in);
    if(inFile->is_open())
    {
        // Read to the the current sensor count
        while(getNextLine(line, 127))
        {
            if(strcmp(line, "<SENSOR>") == 0) // Got one
            {
                if(sNum == m_iNextSensor)
                {
                    // Get data on this one
                    while(getNextLine(line, 127))
                    {
                        // Get the type
                        if(strcmp(line, "<TYPE>") == 0)
                        {
                            if(getNextLine(line, 127))
                            {
                                strcpy(type, line); // Set the type
                            }
                            else
                                return false; // Oops!
                        }
                        else if(strcmp(line, "<MATERIAL>") == 0)
                        {
                            if(getNextLine(line, 127))
                            {
                                strcpy(material, line); // Set the material
                            }
                            else
                                return false; // Oops!
                        }
                        else if(strcmp(line, "<ID>") == 0)
                        {
                            if(getNextLine(line, 127))
                            {
                                *ID = atoi(line); // Set the ID
                            }
                            else
                                return false; // Oops!
                        }
                        else if(strcmp(line, "<UNITS>") == 0)
                        {
                            if(getNextLine(line, 127))
                            {
                                strcpy(units, line); // Set the units
                            }
                            else
                                return false; // Oops!
                        }
                        else if(strcmp(line, "<MINIMUM_VALUE>") == 0)
                        {
                            if(getNextLine(line, 127))
                            {
                                *minVal = atof(line); // Set the minimum value
                            }
                            else
                                return false; // Oops!
                        }
                        else if(strcmp(line, "<MAXIMUM_VALUE>") == 0)
                        {
                            if(getNextLine(line, 127))
                            {
                                *maxVal = atof(line); // Set the minimum value
                            }
                            else
                                return false; // Oops!
                        }
                        else if(strcmp(line, "</SENSOR>") == 0)
                        {
                            m_iNextSensor++; // Increment for next sensor
                            return true; // Got it
                        }
                    } // end while
                } // end if(sNum == m_iNextSensor)
                else
                {
                    sNum++; // Check the next one
                }
            }
        }
        inFile->close();
    } // end if file open
    return false; // If we get here we have got all the sensors
}

edit: the debugger stops at the line of

*maxVal = atof(line); //Set the minimum value

jrdev
  • 125
  • 2
  • 13
  • 2
    You have lot of pointers, but *where do they point?* More specifically, where do `fileName` point when you want to read input from the user? Perhaps you should [get a couple of good books to read](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282)? – Some programmer dude Jul 07 '18 at 19:02
  • `filename` is a `char *`, so `cin >> fileName ;` is not going to work out well for you. – Jesper Juhl Jul 07 '18 at 19:06
  • @JesperJuhl that part actually worked, I can open the file successfully and return the name of the file. when i start parsing the data from the file, it does so successfully until the maxval . – jrdev Jul 07 '18 at 19:07
  • 1
    @jrdev No, you can't. You may think you're doing it successfully, but you're not. You're overwriting something else in memory that you're not aware of, and that may be the source of your bug. Which line of code does the debugger stop at when you see this error? – user1118321 Jul 07 '18 at 19:12
  • @user1118321 oh crap okay, it stops at ` *maxVal = atof(line);` – jrdev Jul 07 '18 at 19:15
  • 1
    You need to allocate memory for maxVal. If it needs to be a pointer then write the declaration as: `double *m_sMaxVal = new double;` . You need to allocate also memory for fileName variable. – AdamF Jul 07 '18 at 19:19
  • @jrdev "compiled and ran as I expected" is a *far cry* from *works*. – Jesper Juhl Jul 07 '18 at 19:27
  • @AdamF that worked! what would happen if i declared my doubles and int as non pointers, dereferenced them, and allocated memory for just the chars? Because I did that as well and the appropriate data is saving to the variables. When I allocated memory for all my variables, the doubles and int saved as memory address locations, not as actual data. just wanna make sure I won't break anything. But thank you so much ! – jrdev Jul 07 '18 at 19:45

1 Answers1

1

When a function or method has a parameter that is a pointer to a variable, you need to allocate memory for that variable. There are a few ways to do that, but the easiest one is to declare an automatic variable like this:

double someVar = 0.0;

and call the function that requires a pointer like this:

SomeFunctionThatTakesADoublePointer(&someVar);

You could allocate the memory on the heap by doing:

double* someVar = new double;

and call the function like this:

SomeFunctionThatTakesADoublePointer(someVar);

This comes with a couple of requirements, though. First, you need to check that the allocation succeeded by wrapping the function call in a conditional, like this:

if (someVar != nullptr)
{
    SomeFunctionThatTakesADoublePointer(someVar);
}

And you have to free the memory when you're done using it, or it will leak:

if (someVar != nullptr)
{
    SomeFunctionThatTakesADoublePointer(someVar);
    // ... do some calculating with *someVar
    delete someVar;
}

Things get trickier with character strings. In C++ you should avoid character strings and use std::string from the standard library. (You'll need to #include <string> to use it.) If you must work with character strings because you're calling a function which you don't control and it requires a string, you need to allocate a string that has enough memory for all the characters and the terminating nul character. You can do that on the stack if you know the length of the string is limited by doing something like:

char someString [ MAX_ALLOWED_STRING_LENGTH + 1 ];

where MAX_ALLOWED_STRING_LENGTH is a constant defined somewhere in your program. Then you can call a function or method which takes a character string like this:

SomeFunctionThatTakeACharacterString(someString);

Again, you could allocate the memory using new [], but you have to ensure it's not nullptr before using it and delete [] it when you're done.

user1118321
  • 25,567
  • 4
  • 55
  • 86