C ++动态分配

时间:2013-06-17 21:28:54

标签: c++ arrays dynamic

我对以下说明非常困惑:

#include <iostream>
#define MAX_IT 100
using namespace std;

class Integer{

private :
    int a;
public:
    Integer(int valoare){a=valoare;}
    int getA(){return a;}
    void setA(int valoare){a=valoare;}
};

int main(){
    Integer* a=new Integer(0);

    //cout<<a[0].getA();
    for(int i=1;i<=MAX_IT;i++)
    {
        a[i]=*(new Integer(i));
    }

    for(int i=0;i<=MAX_IT;i++)
        cout<<a[i].getA()<<endl;

    return 13;
}

它适用于MAX_IT的小值,但是当我尝试将MAX_IT设置为1000时,它不再起作用。 最初,我认为“新”操作员应该完成这项工作,但经过一些阅读文档后,我明白它不应该像这样(超出数组)工作。

所以我的问题是:为什么它适用于MAX_IT的小值而不适用于较大的值?

编辑:

我正在尝试使用此代码来处理更大的程序,我不允许使用STL。你还没有理解我的顾虑:如果我有Integer * var = new Integer [10]; for(int k = 1; K <10; k ++)*(var + k)= k; //这很好,但如果我尝试var [10] = new Integer; //这应该不起作用,应该会产生内存问题//我担心的是,如果我只做了100次左右它就能正常工作......问题是为什么每次迭代次数都很少?

3 个答案:

答案 0 :(得分:17)

因为为一个 Integer分配空间,然后将其用作多个Integer数组,您的代码会调用 undefined行为,意味着它可以做任何事情,包括崩溃,工作似乎很好,或从你的鼻子拉出恶魔。


无论如何,这会泄漏记忆。如果您不需要动态内存分配,请不要使用它。

a[i]=*(new Integer(i));

而且kaboom,你丢失了指向Integer的指针,之后没有机会delete。泄漏。


如果您不需要原始数组,请不要使用它们。首选std::vector。如果C ++太难,可以切换到C.

std::vector<Integer> vec;
vec.push_back(Integer(1337));

答案 1 :(得分:2)

当你稍微溢出缓冲区时,事情往往很好地工作的原因是...... 内存碎片!谁会想到?

为了避免内存碎片,分配器不会返回仅sizeof (Integer)的块。它们会给你一个更大的块,以确保如果块在相邻块之前被释放,它至少足够大,有用。

这有多大可能因架构,操作系统,编译器版本,甚至机器中实际存在多少内存而有所不同。你应该认为它是完全不可预测的。此外,一些旨在帮助捕获此类错误的库会强制将任何小对象放置在块的末尾而不是开头,因此额外的字节可能是负数组索引而不是正数。

因此,不要依赖于在对象之后(或之前)免费提供备用区域。


Guru note:偶尔有人会为额外的内存提供有效的使用,asks for a way to discover how large it is。一个很好的例子是std::vector的容量(不是大小!)可以调整以匹配实际分配的空间而不是请求的空间,因此减少(平均)所需的重新分配的数量。此类请求通常与其他guru分配器API配对,例如,如果恰好存在相邻的空闲块,则可以就地扩展分配。


请注意,在您的特定情况下,您仍然有未定义的行为,因为您在非POD对象上调用operator=,该对象尚未构造。如果你给class Integer一个可以改变的普通默认构造函数。

答案 2 :(得分:0)

你真的需要

Integer* a=new Integer[MAX_IT];

//cout<<a[0].getA();
for(int i=1;i<MAX_IT;i++) << note < not <=
{
    a[i]=i;
}

更好的是使用std :: vector尽管