我正在解決一個簡單的數學問題,該問題需要不斷地將解決方案添加到答案集中。所以我設計了一個類,里面有一個指向指標的指標。每當制定出新的解決方案時,我都會定義另一個新的臨時指標,指向保存答案集資料的指標,并擴大答案集的容量并重新初始化它。然后復制以前的資料并將新的解決方案存盤到答案集。
洗掉臨時指標時,程式總是崩潰到“指定給 RtlValidateHeap 的地址無效”錯誤。正是在洗掉它指向的指標陣列時。
洗掉相應的代碼使一切正常。但我猜由于缺少delete[].
我認為我以正確的方式使用了復制功能,并使每個未使用的指標都指向 NULL。
所以,這是我的代碼:
#include <iostream>
#include "CChickProblem.h"
using namespace std;
int main(int argc, char const *argv[])
{
int n;
cin >> n;
while (n--)
{
int a, b;
cin >> a >> b;
CChickProblem c(a, b);
c.findSolution();
c.printSolution();
}
return 0;
}
CChickProblem.h:
#pragma once
class CChickProblem
{
private:
int cockNum, henNum, chickNum, answerNum, totalNum, totalPrice;
static int singleCockPrice, singleHenPrice, tripleChickPrice, chickenKindNum;
int **answer;
public:
CChickProblem(int money, int number);
~CChickProblem();
void findSolution();
void printSolution();
};
CChickProblem.cpp:
#include <iostream>
#include "CChickProblem.h"
using namespace std;
int CChickProblem::singleCockPrice = 5;
int CChickProblem::singleHenPrice = 3;
int CChickProblem::tripleChickPrice = 1;
int CChickProblem::chickenKindNum = 3;
CChickProblem::CChickProblem(int number, int money)
{
totalNum = number;
totalPrice = money;
cockNum = henNum = chickNum = answerNum = 0;
answer = nullptr;
}
CChickProblem::~CChickProblem()
{
for (int i = 0; i < answerNum; i )
{
delete[] * (answer i);
}
delete[] answer;
}
void CChickProblem::findSolution()
{
for (cockNum = 0; cockNum <= (totalPrice / singleCockPrice); cockNum )
{
for (henNum = 0; henNum <= (totalPrice / singleHenPrice); henNum )
{
for (chickNum = 0; chickNum <= (totalPrice / tripleChickPrice * 3); chickNum = 3)
{
if (cockNum * henNum * chickNum != 0 && cockNum henNum chickNum == totalNum && cockNum * singleCockPrice henNum * singleHenPrice chickNum / 3 * tripleChickPrice == totalPrice)
{
int **extra = new int *[answerNum];
for (int i = 0; i < answerNum; i )
{
*(extra i) = new int[chickenKindNum];
}
copy(answer, answer answerNum, extra);
answer = new int *[ answerNum];
for (int i = 0; i < answerNum; i )
{
*(answer i) = new int[chickenKindNum];
}
copy(extra, extra answerNum - 1, answer);
if (extra)
{
for (int i = 0; i < answerNum - 1; i )
{
if (extra[i])
{
delete[] extra[i];//Where crashes!!
extra[i] = nullptr;
}
}
delete[] extra;
extra = nullptr;
}
*(answer answerNum - 1) = new int[chickenKindNum];
for (int i = 0; i < chickenKindNum; i )
{
switch (i)
{
case 0:
*(*(answer answerNum - 1) i) = cockNum;
break;
case 1:
*(*(answer answerNum - 1) i) = henNum;
break;
case 2:
*(*(answer answerNum - 1) i) = chickNum;
break;
default:
break;
}
}
}
}
}
}
}
void CChickProblem::printSolution()
{
cout << answerNum << endl;
for (int i = 0; i < answerNum; i )
{
for (int j = 0; j < chickenKindNum; j )
{
cout << *(*(answer i) j);
if (j != 2)
{
cout << ' ';
}
else
{
cout << endl;
}
}
}
}
請幫助我,謝謝!
uj5u.com熱心網友回復:
好,朋友們。經過幾天的測驗和嘗試,我弄清楚了這個愚蠢的問題在哪里。嘗試洗掉指標是完全不必要的delete [] extra[i],因為它將洗掉堆上的指向資料,這些資料被安排在以下代碼中重用,而不會洗掉指標本身。并且,由于它已經洗掉了堆中的資料,當程式在解構式處結束時,它會發現沒有任何東西可以銷毀,從而觸發錯誤。因此,在不洗掉指向資料的情況下銷毀指標的正確方法是創建另一個指向原始指向資料的指標,以防您找不到它們并使原始指標指向 NULL。在我的程式中,它應該就像在復制進度后洗掉指向指標的指標。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/464897.html
