簡體   English   中英

VC ++運行時錯誤:調試聲明失敗

[英]VC++ Runtime Error : Debug Assertation Failed

目前,我正在獲得運行時“斷言錯誤”

這是錯誤:

在此處輸入圖片說明

我正在將單詞從文本文件讀取到動態分配的數組中。 這一段代碼是我填充新數組的地方。

我知道問題是由這段代碼引起的,有關我的邏輯的某些信息已關閉,只是看不到它是什么。

  //fill new arrays
    for( int y = 0; y < new_numwords; y++)
    {
        for( int i = 0; i < NUM_WORDS; i++)
        {
            if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
            {
            New_SentenceArry[y] = SentenceArry[i];
            New_WordCount[y] = WordCount[i];
            y++;
            }
        }
    }

另外,如何將這個動態分配的2D數組傳遞給函數? (確實需要對代碼進行整體清理)

char** SentenceArry = new char*[NUM_WORDS]; //declare pointer for the sentence
for( int i = 0; i < NUM_WORDS; i++)
{
SentenceArry[i] = new char[WORD_LENGTH];
}

這是代碼的全部范圍。.非常感謝您的幫助!

這是正在讀取的內容: 在此處輸入圖片說明

和當前的輸出(輸出就是假設的樣子): 在此處輸入圖片說明

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <fstream>
#include <cstring>
#include <cctype>
#include <iomanip>

using std::setw;
using std::left;

using std::cout;
using std::cin;
using std::endl;

using std::ifstream;


int main()
{

const int NUM_WORDS = 17;//constant for the elements of arrays 
const int WORD_LENGTH = 50;//constant for the length of the cstrings (NEED TO GIVE THE VALUE ZERO STILL!)
short word_entry = 0; //declare counter
short new_numwords= 0; //declare new word count
char EMPTY[1][4]; //NULL ARRAY
EMPTY[0][0] = '\0';//define it as null


char** SentenceArry = new char*[NUM_WORDS]; //declare pointer for the sentence
for( int i = 0; i < NUM_WORDS; i++)
{
SentenceArry[i] = new char[WORD_LENGTH];
}

int WordCount[NUM_WORDS];//declare integer array for the word counter

for(int i = 0; i < NUM_WORDS; i++)//fill int array
{
WordCount[i] = 1;
}

int New_WordCount[NUM_WORDS] = {0};

ifstream read_text("DataFile.txt"); //read in our text file

    if (read_text.is_open()) //check if the the file was opened
    {
        read_text >> SentenceArry[word_entry];

        //REMOVE PUNCTUATION BEFORE BEING READ INTO THE ARRAY
        while (!read_text.eof()) 
        {

        word_entry++; //increment counter
        read_text >> SentenceArry[word_entry]; //read in single words of the text file into the array SentenceArry

        char* ptr_ch;//declare our pointer that will find chars

        ptr_ch = strstr( SentenceArry[word_entry], ",");//look for "," within the array

        if (ptr_ch != NULL)//if true replace it with a null character
            {
            strncpy( ptr_ch, "\0" , 1);
            }//end if
                else
                    {

                    ptr_ch = strstr( SentenceArry[word_entry], ".");//look for "." within the array

                        if (ptr_ch != NULL)//if true replace it with a null character
                            {
                            strncpy( ptr_ch, "\0" , 1);
                            }//end if
                    }//end else
            } //end while
    }//end if

    else 
    {
        cout << "The file could not be opened!" << endl;//display error message if file doesn't open
    }//end else

read_text.close(); //close the text file after eof



//WORD COUNT NESTED FOR LOOP
for(int y = 0; y < NUM_WORDS; y++)
{
    for(int i = y+1; i < NUM_WORDS; i++)
    {
        if (strcmp(SentenceArry[y], EMPTY[0]) == 0)//check if the arrays match
        {
            y++;

        }
        else
        {
            if (strcmp(SentenceArry[y], SentenceArry[i]) == 0)//check if the arrays match
            {
                WordCount[y]++;
                strncpy(SentenceArry[i], "\0" , 3);
            }//end if
        }//end if
    }//end for
}//end for


//find how many arrays still contain chars
for(int i = 0; i < NUM_WORDS; i++)
{
    if (!strcmp(SentenceArry[i], EMPTY[0]) == 0) 
    {
    new_numwords++;
    }
}


//new dynamic array
char** New_SentenceArry = new char*[new_numwords]; //declare pointer for the sentence
for( int i = 0; i < new_numwords; i++)
{
New_SentenceArry[i] = new char[new_numwords];
}



//fill new arrays
for( int y = 0; y < new_numwords; y++)
{
        for( int i = 0; i < NUM_WORDS; i++)
        {
        if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
        {
        New_SentenceArry[y] = SentenceArry[i];
        New_WordCount[y] = WordCount[i];
        y++;
        }
    }
}

//DISPLAY REPORT
cout << left << setw(15) << "Words" << left << setw(9) << "Frequency" << endl;
for(int i = 0; i < new_numwords; i++) //compare i to the array constant NUM_WORDS
{
cout << left << setw(15) << New_SentenceArry[i] << left << setw(9) << New_WordCount[i] << endl; //display the contents of the array SentenceArry
}


//DEALLOCATION
for( int i = 0; i < NUM_WORDS; i++)//deallocate the words inside the arrays
{
    delete [] SentenceArry[i];
}

for(int i = 0; i < new_numwords; i++)
{
delete [] New_SentenceArry[i];
}

delete [] SentenceArry; //deallocate the memory allocation made for the array SentenceArry
delete [] New_SentenceArry;//deallocate the memory allocation made for the array New_SentenceArry

}//end main

該代碼存在多個問題,盡管這可以使用C ++編寫,而不是使用C ++ I / O編寫的C。

Issue 1:

由於您使用的是c風格的字符串,因此,字符串數據的任何復制都將需要函數調用,例如strcpy(),strncpy()等。在此代碼中,您沒有遵循以下建議:

for( int y = 0; y < new_numwords; y++)
{
    for( int i = 0; i < NUM_WORDS; i++)
    {
        if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
        {
            New_SentenceArry[y] = SentenceArry[i]; // This is wrong
            New_WordCount[y] = WordCount[i];   
            y++;
        }
    }
}

您應該使用strcpy()而不是=復制字符串。

strcpy(New_SentenceArry[y], SentenceArry[i]);

Issue 2:

您應該為原始數組和新數組分配WORD_LENGTH。 字符串的長度與字符串的數量無關。

char** New_SentenceArry = new char*[new_numwords]; //declare pointer for the sentence
for( int i = 0; i < new_numwords; i++)
{
    New_SentenceArry[i] = new char[new_numwords];
}

應該是:

char** New_SentenceArry = new char*[new_numwords]; //declare pointer for the sentence
for( int i = 0; i < new_numwords; i++)
{
    New_SentenceArry[i] = new char[WORD_LENGTH];
}

Issue 3:

您的循環不會檢查索引是否超出數組的范圍。

看來您是根據當前使用的數據對程序進行編碼的,而不管編寫的代碼是什么,無論數據是什么。 如果您將自己限制在17個單詞以內,那么該索引在16上方的位置在哪里呢? 無處。

例如:

while (!read_text.eof() )

應該:

while (!read_text.eof() && word_entry < NUM_WORDS) 

Issue 4:

您沒有處理正確找到的第一個字符串:

read_text >> SentenceArry[word_entry];  // Here you read in the first word
while (!read_text.eof() ) 
{
     word_entry++; //increment counter
     read_text >> SentenceArry[word_entry]; // What about the first word you read in?

Summary:
即使進行了這些更改,我也無法保證程序不會崩潰。 即使它不會因這些更改而崩潰,我也不能保證它會100%地起作用-保證將需要進一步分析。

考慮到此分配的含義,正確的C ++解決方案是使用std::map<std::string, int>保持單詞頻率。 如果將條目插入地圖,地圖將自動在一個條目中存儲相似的單詞(假設您從單詞中刪除了垃圾),並且該計數將自動增加到1。

像這樣:

#include <string>
#include <map>
#include <algorithm>

typedef std::map<std::string, int> StringMap;
using namespace std;

bool isCharacterGarbage(char ch)
{ return ch == ',' || ch == '.'; }

int main()
{
   StringMap sentenceMap;
   //...
   std::string temp;
   read_text >> temp;
   temp.erase(std::remove_if(temp.begin(), temp.end(), isCharacterGarbage),temp.end());
   sentenceMap[temp]++;
   //...
}

僅此代碼就可以完成原始代碼的所有工作 -跟蹤字符串,提高單詞計數,在處理之前從單詞中刪除垃圾字符等。但是最重要的是, 沒有手動內存管理 沒有對new [],delete []的調用,什么也沒有。 該代碼只是“工作”。 實際上,您只需要編寫5個代碼就可以編寫一個“讀取”循環。

我不會詳細介紹每個細節,因為代碼很小,您可以自己做,因為有大量資源可以解釋std::mapremove_if()等。

然后打印出來只是遍歷地圖並打印每個條目(字符串和計數)。 如果添加打印,則可能是4行額外的代碼。 因此,實際上,幾乎所有的分配工作都有效地執行了大約10行代碼。

刪除以下代碼。

for(int i = 0; i < new_numwords; i++)
{
 delete [] New_SentenceArry[i];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM