[英]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::map
, remove_if()
等。
然后打印出來只是遍歷地圖並打印每個條目(字符串和計數)。 如果添加打印,則可能是4行額外的代碼。 因此,實際上,幾乎所有的分配工作都有效地執行了大約10行代碼。
刪除以下代碼。
for(int i = 0; i < new_numwords; i++)
{
delete [] New_SentenceArry[i];
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.