Vaishnavi Ganseh
Vaishnavi Ganseh

Reputation: 3

C++ 'std::bad_alloc' what(): std::bad_alloc

I am trying to run the below C++ code and I get this error : Could anyone please help me clarify why is this the issue Input : input/text_4.txt 9

terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted (core dumped) After reading a few similar threads, the solution is to check dynamic memory allocation. However, my code does not have any dynamically allocated memory

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>

using namespace std;
vector<string> arrangefile(vector<string>& scale, int width, int &number) {
        int beginning = 0; int total = 0;
        vector<string> result;
        for(int i = 0; i < scale.size(); i++)
        {
            total += scale[i].size(); // add length of each word 

            if(total + i - beginning > width) // checking if the value has exceeded the maximum width 
            {
                total -= scale[i].size(); 
                string sentence= "",low="";
                int last = i-1;
                int space = width - total; // calculate number of spaces in each line
                int check = max(last-beginning, 1); 
                int even = space/check;
                while(even--){
                    low += " ";
                }
                int mod = space%check;
                for(int j = beginning; j <= last; j++)
                {
                    sentence += scale[j]; //find all values in a sentence
                    if(j < last || beginning == last) 
                        sentence += low; // add the word low to the larger sentence
                    if(j - beginning < mod) 
                        sentence += " ";                    
                }
                result.push_back(sentence); // add the sentence to the vector
                number++; // counts the number of sentences
                beginning = i;
                total = scale[i].size();
            }
        }
        
        string sentence =""; // for the last line
        int last = scale.size()-1;
        int check = last-beginning;
        int space = width - total - check;
        string low="";
        while(space--){
            low += " ";
        }
        for(int j = beginning; j <= last; j++)
        {
            sentence += scale[j];
            if(j < last){
                sentence += " "; 
            }               
        }
        sentence += low;
        result.push_back(sentence); // // add the sentence to the vector
        number++; // counts the number of sentences
        return result;
    }

int main(){
    string filepath, word;
    int M, number=0;
    cin >> filepath;
    cin >> M;
    ifstream fin;
    fin.open(filepath.c_str());
    unsigned found = filepath.find_last_of("/");
    string b = filepath.substr(found+1);
    int create = b.size();
    string between = b.substr(0, create-4);
    string final = between + "_formatted.txt";
    string ending = "output/" + final;
    mkdir ("output", 0777);
    ofstream fout;
    fout.open(ending);
    for(int i = 0, count = 0; i<M; i++, count ++){
        if(count == 9){
            fout<<count;
            count = -1;
        }
        else
            fout<<count;
    }
    fout<<endl;
    vector <string> first;
    vector <string> second;
    while(fin >> word){
        first.push_back(word);
    }
    if(first.empty()){
        cout<<"0 formatted lines written to "<< ending<<endl;
    }
    else{
        second = arrangefile(first, M,number);
        for (auto i = second.begin(); i != second.end(); ++i) 
            fout << *i <<endl;
        cout<<number<<" formatted lines written to "<<ending<<endl;
    }
    fin.close();
    fout.close();
    return 0;
}

input file text_4.txt:

This is because not very many happy things happened in the lives of the three Baudelaire youngsters.

Input: input/text_4.txt 8

Upvotes: 0

Views: 855

Answers (1)

Nate Eldredge
Nate Eldredge

Reputation: 58825

When I run your code, on the i==16 iteration of the outer loop in arrangefile, we get width==8 and total==10, with check==1. As a result, even is initialized to -2, and so the while(even--) loop is (nearly) infinite. So it attempts to add spaces to low until it runs out of memory.

(Note that the memory used by std::string is dynamically allocated, so your code does have dynamic memory allocation. The same for std::vector.)

I haven't analyzed your algorithm closely enough to figure out the correct fix, but it's possible your loop should be while(even-- > 0) instead.


I'll second the tip in the comments to use your debugger, and I'll repost the link: What is a debugger and how can it help me diagnose problems?. That's how I found this bug.

I ran the program under the debugger gdb. It ran for a few seconds, at which point I got suspicious because the program doesn't appear do anything complicated enough to take that much computation time. So I interrupted the program (Ctrl-C) which let me see where it was and what it was doing. I could see that it was within the while(even--) loop. That was also suspicious because that loop should complete very fast. So I inspected the value of even (with the command p even) and saw that it was a large negative number. That could only happen if it had started as a negative number, which logically could only happen if total were greater than width. Inspecting their values I could see that this was indeed the case.

Maybe this will be helpful as you learn more about using your debugger.

Upvotes: 4

Related Questions