【问题标题】:(C++) terminate called after throwing an instance of 'std::bad_alloc'(C++) 在抛出 'std::bad_alloc' 的实例后调用终止
【发布时间】:2016-09-08 16:02:56
【问题描述】:

我不断收到错误的内存分配错误。我整晚都在试图找出我错在哪里,但我不知道是什么。

我已经梳理了每一行,但仍然一无所获。会不会是我的程序/笔记本电脑不够强大?

任何帮助都会非常有帮助。我的头在响,我需要休息一下。 这是我的代码:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

// struct to store word + count combinations
struct wordItem{
    string word;
    int count;
};

void getStopWords(char *ignoreWordFileName, vector<string>& _vecIgnoreWords);

bool isCommonWord(string word, vector<string>& _vecIgnoreWords);

void printTopN(wordItem wordItemList[], int topN);

void doubleArray(wordItem wordItemList[], int size);

int getTotalNumberNonCommonWords(wordItem wordItemList[], int size, int wordCount);

const int STOPWORD_LIST_SIZE = 50;

// ./a.out 10 HW1-HungerGames_edit.txt HW1-ignoreWords.txt
int main(int argc, char* argv[]){

    vector<string> vecIgnoreWords(STOPWORD_LIST_SIZE);

    // verify we have the correct # of parameters, else throw error msg & return
    if (argc != 4){
        cout << "Usage: ";
        cout << argv[0] << " <number of words> <filename.txt> <ignorefilename.txt>"<< endl;
        return 0;
    }

    //Set vector with stop words
    getStopWords(argv[3], vecIgnoreWords);

    //initialize struct array
    int aSize = 100;
    wordItem *theStructArray = new wordItem[aSize];
    int counter = 0;
    int doubleCount = 0;

    //read main txt file
    ifstream inFile(argv[1]);

    if(inFile.is_open()){
        string line;
        string theWord;

       //extract words from file
        while(getline(inFile, line)){
            istringstream iss(line);

            //extract and analyze word
            while(iss >> theWord){
                if(!(isCommonWord(theWord, vecIgnoreWords))){
                    bool inStructArray = false;
                    int inStructPosition;

                    //search for word in Struct array
                    while (inStructArray == false){
                        for(int i=0; i<aSize; i++){
                            if (theWord == theStructArray[i].word){
                                inStructArray = true;
                                inStructPosition = i;
                            }
                        }
                        break;
                    }

                    //if word is in struct array
                    if (inStructArray == true){
                        theStructArray[inStructPosition].count++;
                    }

                    //else if it isn't
                    else{
                        //create new wordItem and add into struct                           
                        wordItem newWord;
                        newWord.word = theWord;
                        newWord.count = 1;

                        theStructArray[counter+(100*doubleCount)] = newWord;
                        counter++;
                    }

                    //if struct array hits maximum amount of elements,
                    if (counter == (aSize-1)){
                        doubleArray(theStructArray, aSize);
                        counter = 0;
                        doubleCount++;
                        aSize +=100;
                    }
                }
            }   
        }
        inFile.close();
    }

    //Bubble sort masterArray
    int bI, bJ, flag = 1;
    wordItem bTemp;

    for(bI=1; (bI <= aSize && flag); bI++){
        flag = 0;
        for(bJ=0; bJ<aSize; bJ++){
            if(theStructArray[bJ+1].count > theStructArray[bJ].count){
                bTemp = theStructArray[bJ];
                theStructArray[bJ] = theStructArray[bJ+1];
                theStructArray[bJ+1] = bTemp;
                flag = 1;   
            }
        }
    }

    //Print topN words
    printTopN(theStructArray, atoi(argv[1]));

    //print others
    cout << "#" << endl;
    cout << "Array doubled: " << doubleCount << endl;
    cout <<"#" << endl;
    cout << "Unique non-common words: "<< (aSize-100+counter)<<endl;
    cout << "#"<<endl;
    cout <<"Total non-common words: "<< getTotalNumberNonCommonWords(theStructArray, aSize, counter)<<endl;

    return 0;
}

void getStopWords(char *ignoreWordFileName, vector<string>& _vecIgnoreWords){

    ifstream inFile(ignoreWordFileName);

    if(inFile.is_open()){
        int a = 0;
        string line;

        while(getline(inFile, line)){
            _vecIgnoreWords.insert(_vecIgnoreWords.begin() + a, line);
        }
        inFile.close();
    }
    return;
}

bool isCommonWord(string word, vector<string>& _vecIgnoreWords){

    for(int i=0; i<STOPWORD_LIST_SIZE; i++){
        if(word == _vecIgnoreWords.at(i)){
            return true;
        }
    }
    return false;
}

void printTopN(wordItem wordItemList[], int topN){

    cout << endl;

    for(int i=0; i<topN; i++){
        cout<< wordItemList[i].count << '-' << wordItemList[i].word << endl;
    }
    return;
}

void doubleArray(wordItem wordItemList[], int size){

    wordItem *tempArray = new wordItem[size+100];

    for(int i=0; i<size; i++){
        tempArray[i] = wordItemList[i];
    }

    delete [] wordItemList;
    wordItemList = tempArray;

}

int getTotalNumberNonCommonWords(wordItem wordItemList[], int size, int wordCount){

    int total = 0;
    for(int i=0; i<(size-100+wordCount); i++){
        total+=wordItemList[i].count;
    }
    return total;
}

【问题讨论】:

  • 你知道你程序的哪一行导致了异常吗?
  • "会不会是我的程序/笔记本电脑不够强大?"你是什​​么意思?您是否尝试过检查要分配多少内存,并尝试了一个琐碎的void main(…) { malloc(…); }?你检查过valgrind吗?另外,请阅读并关注How to create a Minimal, Complete, and Verifiable example
  • 仅供参考,您的冒泡排序中的theStructArray[bJ+1] 最终将在每个内部循环的最后一次迭代中访问越界。外循环限制也是错误的。仅此一项就会引发未定义的行为。我敢肯定这里还有更多。您需要在调试器中运行此代码
  • 为什么要混合使用vector 和手动内存管理?
  • '我的脑袋嗡嗡作响,我需要休息' - 所以你们去解决我的代码的问题。

标签: c++ memory-management dynamic-memory-allocation


【解决方案1】:

你在void doubleArray(wordItem wordItemList[], int size)做坏事

如果你传递一个数组,你可以在数组上调用delete [],但你不能改变它的值,所以doubleArray(theStructArray, aSize);会导致theStructArray被删除,但不会分配给你分配的内存。您只是在函数doubleArray中分配局部变量

类似于:

void doubleit(int x)
{
   x *= 2;
}

int y=3;
doubleit(y);

这里 x 暂时翻倍到 6,但 y 从未改变。

您需要使用引用,或者最好将 theStructArray 设置为 std::vector 并完成它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多