我正在编写程序,以便在动态分配的数组中引入,然后再打印它。如果我只介绍一组值,一切都很好,但如果我引入更多的那一对值,程序就会崩溃。
#include <iostream>
#include <stdlib.h>
using namespace std;
int *a, *b, m;
void askData(int **a, int **b);
void printData(int **a, int **b);
int main(){
bool control = true;
do{
cout <<" ************* MENU ************* "<< endl;
cout <<" 1.- Ask for values "<< endl;
cout <<" 2.- Print values "<< endl;
cout <<" 3.- Exit "<< endl;
cout << "Select one option: " << endl;
int n;
cin >> n;
switch(n){
case 1:
askData(&a,&b);
cout << endl;
break;
case 2:
printData(&a,&b);
break;
default:
cout << "Exit" << endl;
break;
}
system("pause");
system("cls");
if(n == 3){
control = false;
}
}while(control);
return 0;
}
void askData(int **a, int **b){
cout << endl << "Enter the number of pairs of data: ";
cin >> ::m;
int z = ::m;
*a = new int[z];
*b = new int[z];
for(int i=0; i<z; i++){
cout << "Enter V[" << i <<"], Enter T[" << i << "]:?";
cin >> *a[i] >> *b[i];
}
delete [] a;
delete [] b;
}
void printData(int **a, int **b){
for(int i=0; i < m; i++){
cout << *a[i] << " " << *b[i] << endl;
}
}
答案 0 :(得分:2)
你试图在释放它(悬空指针)之后读取内存,这将有未定义的行为。
您的函数 askData 正在分配内存并填充数据。但是在此函数的末尾,您将释放存储在全局变量 a &amp;中的内存。 b
现在在 printData ()函数内部,您正在传递要读取的已释放内存指针。这会导致问题。
<强> EDIT1 强>
我们应该避免使用原始指针而不是使用C ++提供的智能指针。在这种情况下,您不必担心手动内存管理。
<强> EDIT2 强>
您的程序正在尝试写入 a &amp; b (指向指针的指针)。无论如何,对于您的程序,您可以删除传递给不同函数的参数,因为它们是全局变量。但我建议你开始使用 std :: vector 和 smart_pointer 。
了解如何使用ISOCPP FAQ链接中的这些概念:
http://isocpp.org/wiki/faq/freestore-mgmt#memory-leaks
void askData(){
a = new int[z];
b = new int[z];
for(int i=0; i<z; i++){
cout << "Enter V[" << i <<"], Enter T[" << i << "]:?";
cin >> a[i] >> b[i];
}
}
void printData(){
for(int i=0; i < m; i++){
cout << a[i] << " " << b[i] << endl;
}
delete [] a;
delete [] b;
}
答案 1 :(得分:2)
在askData
函数中创建动态数组时,需要将数组取消引用为:
for(int i=0; i<z; i++){
cout << "Enter V[" << i <<"], Enter T[" << i << "]:?";
cin >> (*a)[i] >> (*b)[i];
}
对于printData
函数,您需要将它们取消引用为:
for(int i=0; i < m; i++){
cout << (*a)[i] << " " << (*b)[i] << endl;
}
请注意,当您使用
时*a = new int[z];
*b = new int[z];
*a
和*b
是指向大小为z
的整数数组的指针。并且a
和b
是指向函数参数列表中定义的指针的指针。
您还需要按照其他人的建议将这两行注释掉
//delete [] a;
//delete [] b;
不要忘记在printData
结束时释放记忆。
答案 2 :(得分:0)
做
delete [] a;
delete [] b;
删除了内存,即不再分配数组并从堆中删除数据。
答案 3 :(得分:0)
首先,我建议您将全局变量置于本地并初始化它们。更容易解决出错的问题。
int *a = 0, *b = 0, m;
要拉出局部变量,您需要为askData()
添加第三个参数,并为数组的大小添加printData()
。
void askData(int **a, int **b, int &m); // m is by reference because you want to return the size
void printData(int **a, int **b, int m);
方法askData()
应该检查a
和b
是否已经指向内存,在分配更多内容之前应该释放内存
if( *a != 0 )
{
delete [] *a;
}
*a = new int[m];
if( *b != 0 )
{
delete [] *b;
}
*b = new int[m];
由于您传递的是m
,因此您无需声明z
。
cout << endl << "Enter the number of pairs of data: ";
cin >> m; // Just use m
...
for(int i=0; i<m; i++){
cout << "Enter V[" << i <<"], Enter T[" << i << "]:?";
cin >> (*a)[i] >> (*b)[i];
}
接下来,您的程序会分配您需要处理的内存。这不应该发生在askData()
,但是在你知道你不再需要那个记忆之后。在您的情况下,我建议将其放在main()
的末尾附近。在尝试删除它们之前,您应该检查它们是NULL
,还是0
if( a != 0 )
{
delete [] a; // No asterick because these are `int*`
}
if( b != 0 )
{
delete [] b;
}
你修改的程序看起来像这样
#include <iostream>
#include <stdlib.h>
using namespace std;
void askData(int **a, int **b, int &m);
void printData(int **a, int **b, int m);
int main(){
int *a = 0, *b = 0, m; // These are now local, much better
bool control = true;
do{
cout <<" ************* MENU ************* "<< endl;
cout <<" 1.- Ask for values "<< endl;
cout <<" 2.- Print values "<< endl;
cout <<" 3.- Exit "<< endl;
cout << "Select one option: " << endl;
int n;
cin >> n;
switch(n){
case 1:
askData(&a,&b, m);
cout << endl;
break;
case 2:
printData(&a,&b, m);
break;
default:
cout << "Exit" << endl;
break;
}
system("pause");
system("cls");
if(n == 3){
control = false;
}
}while(control);
if( a != 0 )
{
delete [] a;
}
if( b != 0 )
{
delete [] b;
}
return 0;
}
void askData(int **a, int **b, int &m){
cout << endl << "Enter the number of pairs of data: ";
cin >> m;
if( *a != 0 )
{
delete [] *a;
}
*a = new int[m];
if( *b != 0 )
{
delete [] *b;
}
*b = new int[m];
for(int i=0; i<m; i++){
cout << "Enter V[" << i <<"], Enter T[" << i << "]:?";
cin >> (*a)[i] >> (*b)[i];
}
}
void printData(int **a, int **b, int m){
for(int i=0; i < m; i++){
cout << (*a)[i] << " " << (*b)[i] << endl;
}
}