0

I created a vector of vector (10*10000) and try to access this vector through member function. but I got a segmentation fault. I don't know what's wrong here...

Here is Simple.h

class Simple 
{
private:
    std::vector<double> data_row;
    std::vector<std::vector<double> > data;
public:
    
    Simple():data_row(10000), data(10, data_row){};
    /*initialize data vector*/
    int getSampleCounts(std::istream &File);
    /*return number of packet samples in this file*/
    Result getModel(std::istream &File);
    /*return average and variance of simple delta time*/
    void splitData (std::istream &File, const int & sample_in_fold);
};

#endif  /* SIMPLE_H */

here is Simple.cpp

void Simple::splitData(std::istream& File, const int & sample_in_fold) {
    double value = 0.0;
    bool isFailed = true;

    int label = 0;
    while (File >> value) {
        // for each value, generate a label
        srand(time(NULL));
        label = rand() % 10; // generate label between 0 to 9
        while (isFailed) {
            // segmentation fault in the next line!
            std::cout << "current data size is: " << this->data.size() <<endl; 
            std::vector<double>::size_type sz = this->data[label].size();
            if (sz <= sample_in_fold) {
                std::cout << "current size is " << sz << "< samples in fold: " << sample_in_fold << endl;
                this->data[label].push_back(value);
                std::cout << "push_back succeed!" << endl;
                isFailed = false;
            } else {
                std::cout << "label " << label << "if full. Next label. \n";
                srand(time(NULL));
                label = rand() % 10;
                sz = this->data[label].size();
            }
        }
    }
}

and I'm attaching the main file here.

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib> // for system())
#include <sys/types.h>
#include <dirent.h>
#include <vector>
#include <limits.h> // for PATH_MAX
#include "Complex.h"
#include "Result.h"
#include "Simple.h"
#include <math.h> 

using namespace std;

int main(int argc, char ** argv) {
    struct dirent *pDirent;
    DIR *pDir;
    std::string line;

    // check for args
    if (argc == 1) {
        printf("Usage: ./main + folder name. \n");
        return 1;
    }

    pDir = opendir(argv[1]);
    if (pDir == NULL) {
        printf("Cannot open directory '%s' \n", argv[1]);
        return 1;
    }

    // readdir returns a pointer to the next directory entry dirent structure
    while ((pDirent = readdir(pDir)) != NULL) {
        // get file name and absolute path
        char *name = pDirent->d_name;
        char buf[PATH_MAX + 1];
        realpath(name, buf);
        //        std::cout << "Current file is: " << (pDirent->d_name) << endl;

        if (has_suffix(pDirent->d_name, ".txt")) {
            printf("[%s]\n", pDirent->d_name);
            //printf("absolute path is %s. \n", buf);

            ifstream infile;

            // open file with absolute path
            infile.open(buf, ios::in);

            if (!infile) {
                cerr << "Can't open input file " << buf << endl;
                exit(1);
            }

            //processing for simple pattern
            if (has_suffix(name, "testfile.txt")) {
                Simple* simple_obj;
                int number = simple_obj->getSampleCounts(infile);
                Result simplerst = simple_obj->getModel(infile);
                std::cout << "Number of delta time is " << number << endl;

                infile.clear();
                infile.seekg(0);
                
                write_to_file(pDirent->d_name, simplerst);

                // divide data into k = 10 folds, get number of data in each fold
                int sample_in_fold = floor(number / 10);
                std::cout << sample_in_fold << std::endl;
                simple_obj->splitData(infile, sample_in_fold);

            }
        } else {
            //            printf("This is not a txt file. Continue\n");
        }
    }
    closedir(pDir);
    return 0;


}

And here is a sample testfile.txt. I only copied part of the original file, for illustration.

10.145906000
10.151063000
10.131083000
10.143461000
10.131745000
10.151285000
10.147493000
10.123198000
10.144975000
10.144484000
10.138129000
10.131634000
10.144311000
10.157710000
10.138047000
10.122754000
10.137675000
10.204973000
10.140399000
10.142194000
10.138388000
10.141669000
10.138056000
10.138679000
10.141415000
10.154170000
10.139574000
10.140207000
10.149151000
10.164629000
10.106818000
10.142431000
10.137675000
10.204973000
10.140399000
10.142194000
10.138388000
10.141669000
10.138056000
10.138679000
10.141415000

Here is Result.h

#ifndef RESULT_H
#define RESULT_H

typedef struct Result {
    double average;
    double sigma;
}Result;

and getModel function in Simple.cpp:

Result Simple::getModel(std::istream &File) {

    double value = 0.0;
    double average = 0.0;
    double sum = 0.0;
    double counter = 0.0;
    double sumsqr = 0.0;
    double var = 0.0;
    double sigma = 0.0;
    while (File >> value) {
        ++counter;
        sum += value;
        sumsqr += value * value;
    }

    average = sum / counter;
    var = sumsqr / counter - average * average; //E(x^2) - (E(x))^2
    sigma = sqrt(var);

    std::cout << "average is " << average << std::endl;
    std::cout << "std deviation is " << sigma << std::endl;

    File.clear();
    File.seekg(0);

    Result result = {average, sigma};
    return result;
}
9
  • When do you get a segmentation fault? Is it when calling the splitData function? Commented Jun 4, 2015 at 18:30
  • @RobinHartland when accessing this->data.size() in splitData function Commented Jun 4, 2015 at 18:40
  • vector<vector> is usually a bad design, unless you have to keep memory consumption low. Commented Jun 4, 2015 at 18:41
  • runs fine on my computer... Commented Jun 4, 2015 at 18:57
  • are you sure you declare data_row and data in the same order as you do here? if data is defined above data_row in your full class it will break due to how you initialize them Commented Jun 4, 2015 at 19:01

2 Answers 2

4

One issue right away:

Simple* simple_obj;
int number = simple_obj->getSampleCounts(infile);

simple_obj is an uninitialized pointer, thus your program exhibits undefined behavior at this point.

Why use a pointer anyway? You could have simply done this to avoid the issue:

Simple simple_obj;
simple_obj.getSampleCounts(infile);

Also, this line may not be an issue, but I'll mention it anyway:

Result simplerst = simple_obj->getModel(infile);

We already know that in your original code, simple_obj is bogus, but that's not the issue here. If Result is an object, and that object does not have correct copy semantics, then that assignment will also cause undefined behavior.

Sign up to request clarification or add additional context in comments.

5 Comments

thank you! Result is a struct, and getModel function returns an object of Result, so I create simplerst... will that also have the problem?
It depends on what members are in the struct. Post the Result struct in your original question, as this could be a further issue.
ok. Result is fine. It will copy over with no issues. Wait -- one small issue -- make sure that your members are initialized before you copy. Copying uninitialized floating point variables is undefined behavior.
@pinteson, it looks like this helped you fix the problem, so if you could accept this answer by making the tick on the left of this answer go green, that would show everyone this, and give PaulMcKenzie the extra rep he deserves
@RobinHartland yes, sorry I'm new to this.
0

You've got a couple of uses of endl without specifying std::endl (they're not the same thing - you always have to type the std:: ). Is endl silently referring to another variable somewhere else?

7 Comments

nope... i have using namespace std on the top, and the problem remains after I added std::
If you get rid of using namespace std? It is mildly evil.
Have you corrected all the endl's - the one on the seg fault line, the one after cout << "samples in fold: " and the one after "push_back succeed!"? Any of them could be referring to something else, as you've thrown open the std namespace but are still strangely qualifying most std things with "std::" !
yes, i've deleted using namespace std and replaced all with std::
In that case, can you give a nice minimal, complete example (stackoverflow.com/help/mcve)? It runs fine on my machine, and fine on Sean's, above.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.