动态内存分配有不希望的输出 [英] Dynamic memory allocation has undesired output

查看:109
本文介绍了动态内存分配有不希望的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我上周开始学习C ++,自然,我想熟悉整个指针和面向对象的业务等等。



这样,我为一些基本的矩阵计算编写了一个非常简单的程序:

 #include< iostream> 
using std :: cout;
using std :: cin;

class Matrix {
int columns; // x
int rows; // y
double * matrix;
public:
Matrix(int *);
void printMatrix();
void free(){
delete [] matrix;
return;
};
};

Matrix :: Matrix(int * dim){
rows = * dim;
columns = *(dim + 1);
matrix = new double [columns * rows];
}

void Matrix :: printMatrix(){
int i,j;
for(i = 0; i for(j = 0; j< rows; j ++){
cout<矩阵[列* i + j] ;
}
cout<< \\\
;
}
return;
}


int * getMatrix();

int main(){
矩阵矩阵(getMatrix());
matrix.printMatrix();
matrix.free();
return 0;
}

int * getMatrix(){
int * dim = new int [2];
cout<< (m×n)-Matrix,m;
cin>> dim [0]
cout<< n?;
cin>> dim [1];
return dim;
}

当我选择一个(4, 2)矩阵。根据各种教程的理解,

  matrix = new double [columns * rows] 

应该分配这么多内存: columns * rows (双)。此外,每个单元格应使用 0 初始化。



但是,选择一个输出的函数printMatrix():

  0 0 
0 0
0 6.6727e-319
0 0

为什么


此外,每个cell都应该用0初始化。


当你写 new double [N] 时,语言不会为你这么做。


为什么(3,2)条目不用0初始化?


如果写入 new double [N]() instead!


11:5.3.4 / 15]:创建 T 类型的对象的 new-expression 如下:




  • 如果省略了 new-initializer ,则对象是 default-initialized (8.5)。

  • 否则, new-initializer 将根据8.5的初始化规则解释为 direct - 初始化


授予,这有点模糊,正在谈论非数组版本的 new ,但实际上它意味着两者; T double [4]



,我们可以看到同一部分的措辞在数组和非数组情况下谈论对象,设置完美的先例:


[C ++ 11:5.3.4 / 1]: [..]如果实体是非数组对象, new-expression 返回指向所创建对象的指针。如果它是一个数组,new-expression
返回指向数组的初始元素的指针。


它本质上不可能证明这条规则,因为你可以击中不幸,获得全零,即使这些值实际上是不确定的,但下面的代码完全不令人信服地创造了一个好的开始:

  #include< iostream> 
#include< vector>

int main(){
const std :: size_t n = 4;

{
std :: vector< double>黑客
hack.push_back(5);
hack.push_back(6);
hack.push_back(7);
hack.push_back(8);
hack.push_back(9);
hack.push_back(10);
hack.push_back(11);
hack.push_back(12);
}

double * a = new double [n];
double * b = new double [n]();

for(std :: size_t i = 0; i std :: cout< a [i]< '/'<< b [i]< '';
std :: cout<< '\\\
';

delete [] a;
delete [] b;
}

我设法获得 0/0 6/0 7/0 8/0 ,由于一些堆hackery,但它仍然只是纯粹的机会,并没有真正展示任何东西( new double [4]。[/ b] (316)无效(在直接初始化期间,()中的值明确禁止数组> [C ++ 11:8.5 / 16] ),所以我们不能建议 new double [4] code>将是可靠的,并使用 316 的示例来说服您。


So I started learning C++ last week and naturally, I want to become familiar with the whole pointer and object-oriented business and so on and so forth.

To do that, I'm writing a very simple program for some basic matrix calculations:

# include <iostream>
using std::cout;
using std::cin;

class Matrix {
        int columns; // x
        int rows; // y
        double* matrix;
    public:
        Matrix (int*);
        void printMatrix();
        void free() {
            delete[] matrix;
            return;
            };
};

Matrix::Matrix(int* dim){
    rows = *dim;
    columns = *(dim + 1);
    matrix = new double [columns*rows];
}

void Matrix::printMatrix(){ 
    int i, j;
    for(i = 0; i < columns; i++){
        for(j=0; j < rows; j++){
            cout << matrix[columns*i + j] << " ";
        }
        cout << "\n";
    }
    return;         
}


int* getMatrix ();

int main () {
    Matrix matrix (getMatrix());
    matrix.printMatrix();
    matrix.free();
    return 0;
}

int* getMatrix (){
    int* dim = new int [2];
    cout << "(m x n)-Matrix, m? ";
    cin >> dim[0];
    cout << "n? ";
    cin >> dim[1];
    return dim;
}

The problem (as I see it) occurs when I choose a (4,2) matrix. As I understand from various tutorials,

matrix = new double [columns*rows];

should allocate this much memory: columns*rows times sizeof(double). Also, every 'cell' should be initialized with a 0.

But, choosing a (4,2) matrix, I get the following output, of the function printMatrix():

0 0 
0 0 
0 6.6727e-319 
0 0 

Why is the (3,2) entry not initialized with 0?

Thanks!

解决方案

Also, every 'cell' should be initialized with a 0.

Nope. The language does not do that for you, when you write new double[N].

Why is the (3,2) entry not initialized with 0?

It will if, you write new double[N]() instead!

[C++11: 5.3.4/15]: A new-expression that creates an object of type T initializes that object as follows:

  • If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed, the object has indeterminate value.
  • Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.

Granted, this is slightly ambiguous in that it would seem to be talking about the non-array versions of new, but in fact it means both; T is double[4].

In fact, we can see that the same section of wording talks about "object" in both the array and non-array cases, setting the perfect precedent:

[C++11: 5.3.4/1]: [..] If the entity is a non-array object, the new-expression returns a pointer to the object created. If it is an array, the new-expression returns a pointer to the initial element of the array.

Now, it's essentially impossible to prove this rule, because you can strike unlucky and get all-zeroes even when those values are in fact indeterminate, but the following code entirely unconvincingly makes a good start:

#include <iostream>
#include <vector>

int main() {
    const std::size_t n = 4;

    {
        std::vector<double> hack;
        hack.push_back(5);
        hack.push_back(6);
        hack.push_back(7);
        hack.push_back(8);
        hack.push_back(9);
        hack.push_back(10);
        hack.push_back(11);
        hack.push_back(12);
    }

    double* a = new double [n];
    double* b = new double [n]();

    for (std::size_t i = 0; i < n; i++)
        std::cout << a[i] << '/' << b[i] << ' ';
    std::cout << '\n';

    delete[] a;
    delete[] b;
}

I managed to get 0/0 6/0 7/0 8/0 from it, thanks to some heap hackery, but it's still only just pure chance and doesn't really demonstrate anything (live demo).

Unfortunately, new double[4](316) isn't valid (providing a value inside the () is explicitly banned for arrays during direct-initialization, per [C++11: 8.5/16] ) so we can't suggest that new double[4](0) would be reliable and use the example with 316 to convince you of it.

这篇关于动态内存分配有不希望的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆