0

Can't seem to figure out why exactly this program won't work. It is supposed to store data from a csv file into a structure called SurnameInfo (when used with a loop that iterates through each line) but whenever I run it it gets to line 1280 of 151671 of the csv file, crashes, and gives the windows "program.exe has stopped working" popup. Anyone see anything that might cause this? Thanks!!

#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
using namespace std;

const int MAXLINE = 1000;
const int MAXARRAY = 1000;
int numberOfNames;

struct SurnameInfo
{
    char *name;
    int count;
    float pctrace[6];
};
SurnameInfo*surnames[MAXARRAY];

void processLine(char *line, int n)
{
    surnames[n] = new SurnameInfo; //allocate memory
    char * pch = strtok(line, ",");//start tokenizing
    int len = strlen(pch); // name length
    surnames[n]->name = new char[len+1]; //allocate memory
    strcpy(surnames[n]->name, pch); // copy name
    surnames[n]->count = atoi(strtok(NULL, ","));//get count
    for (int i = 0; i < 6; i++)
    {
        pch = strtok(NULL, ",");
        surnames[n]->pctrace[i] = pch[0] == '(' ? -1 : atof(pch);
    }
}

void readLines()
{
    char line[MAXLINE];
    ifstream inputfile;
    inputfile.open("names.csv");
    if (!inputfile) return; // can't open
    inputfile.getline(line, MAXLINE); //skip title
    inputfile.getline(line, MAXLINE);
    numberOfNames = 0;
    while (!inputfile.eof()) //not end of file
    {
        processLine(line, numberOfNames++);
        inputfile.getline(line, MAXLINE);
    }
    inputfile.close();
}

int main() {
readLines();

return 0;
}
David Ching
  • 1,903
  • 17
  • 21
  • 1
    Have you tried finding the exact error? Catching exceptions, checking event log, etc? – Nic Mar 10 '15 at 00:50
  • Try running it in the debugger. – markgz Mar 10 '15 at 00:51
  • horrible code. Please use std::string instead of char*. – The Vivandiere Mar 10 '15 at 00:51
  • 3
    You said there are 151671 lines in the CSV file. Your per-line array of structure pointers is only 1000 elements long (`SurnameInfo*surnames[MAXARRAY];`, where you declare `const int MAXARRAY = 1000;`). I'm surprised it made it to 1280 before it finally bit the dust. that's 280 more pointers than you have space for. – WhozCraig Mar 10 '15 at 00:53
  • The code is for a class I am taking and these functions were given to us by a professor. So I have to use char* but as I am very new to c++ I didn't really know any better anyway. – mtihlenfield Mar 10 '15 at 00:57
  • https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – Galik Mar 10 '15 at 01:07

1 Answers1

1

I see a discrepancy in the code and the stuff that you are talking. const int MAXARRAY = 1000; && SurnameInfo*surnames[MAXARRAY]; goes against 151671 of the csv file.

You are allocating 1000 and trying to push more to the heap unattended which means it starts eating the memory allocated to the program itself. Or it tries to access the area which it is not supposed to (may be program area of some other process is allocated), and thus pushes out a Segmentation Fault

Also, you need to have a way to destruct the Surnames that are dynamically fed.

My Suggestion :

Approach 1 : Read through the file first and get the number of lines. Allocate the respective memory to Surnames and proceed the way you are. Though it requires one additional scan of file, but would solve your purpose. Time complexity goes very high if the file size is high.(May be you can cache stuff while reading , use vector?? (think on that))

Approach 2 : Implement a functionality similar to resize of vector.On every new addition to the Surnames, Free the previously allocated memory on heap and reallocate with the higher memory spec by deep copying and inserting new info.

Also,

surnames[n]->pctrace[i] = pch[0] == '(' ? -1 : atof(pch);

I am not very sure whether this would work correctly or not. Just for the sake of safety and more clear code, put that up in parenthesis . Something like this

surnames[n]->pctrace[i] = ((pch[0] == '(') ? -1 : atof(pch));

If this is your one of the first attempts on C++, this is nicely done. Cheers.

Hope the answer helps.

Sameer Sawla
  • 729
  • 6
  • 20