【问题标题】:How is memory allocated to instances of class with array member?如何将内存分配给具有数组成员的类的实例?
【发布时间】:2017-09-09 11:01:57
【问题描述】:

据我了解,在通常情况下,数组是在编译时分配内存的,但是当数组是成员变量时会发生什么,并且在编译期间几乎没有什么可以分配内存的。当创建该类的实例时,它是否会被隐式动态分配?

class Arr{
   public:
   int arr[10];
};

Arr doSomething(Arr &arg){
   return arg; //copy of arg created; 'copy=new int[10]' at this point?
}

int main(){
   Arr temp; 
   doSomething(temp);

   //if returned object's array was dynamically initialized
   //will it result the array in temp being released twice?
}

UPD。 就我而言,当我尝试在 B>A 中减去 A-B 时,情况就会上升。在这些情况下,我可以访问数组以从中读取,但修改它的值会导致垃圾。此外,main 的最终输出很好。完整代码如下:

#include <iostream>

using namespace std;

const int MAX_ARRAY_SIZE=256;

char* getOperatorIndex(char* equationString);
bool isOperator(char characterDec);
int* toIntArray(char* firstInA, char* lastInA, int* firstInB);

class Number{
    int* firstInNumber;
    int* lastInNumber;
    int number[MAX_ARRAY_SIZE];

    public:
    Number();
    ~Number();
    bool operator<(Number& b);
    int& operator[](int index);
    Number operator-(Number& b);
    void print();
    int length(){return lastInNumber-firstInNumber;}
    int*& lastPtr(){return lastInNumber;}
    int*& firstPtr(){return firstInNumber;}
};

Number::Number(){
    firstInNumber=number;
    lastInNumber=number;
}

Number::~Number(){
    cout<<"number destroyed"<<endl;
}

int& Number::operator[](int index){
    return number[index];
}

bool Number::operator<(Number& b){
    if(length()>b.length())return false;
    if(length()<b.length())return true;

    for(int a=0;a<length();++a){
        if(number[a]>b[a])return false;
        if(number[a]<b[a])return true;
    }
    return false;

}

void Number::print(){
    for(int a=0; a<=length(); ++a){
        cout<<number[a];
    }
    cout<<endl;
}

Number Number::operator-(Number& b){

    Number result;

    if(*this < b)
    {
        result=b-*this;
        cout<<*result.lastPtr()<<endl;
        result.print();
        *result.lastPtr()*=-1; // GARBAGE HERE
        cout<<*result.lastPtr()<<endl;
        return result;
    } 

    result[0]=0;

    for(int q=0; q<=length(); ++q)
    {

        if(b.length()-q >= 0)
        {
            result[q]+=(*this)[length()-q]-b[b.length()-q];

            if(result[q] < 0)
            {
                result[q]+=10;
                result[q+1]=-1;

            } 
            else
            {
                result[q+1]=0;
            }

        }
        else
        {
            result[q]+=(*this)[length()-q];

        }

    ++result.lastPtr(); 
    }

    do{
        --result.lastPtr();
    }while(!*result.lastPtr());

    return result;
}

int main(){
    char equationArray[MAX_ARRAY_SIZE*2+1];  // operandA(<=256) operator(1) operandB(<=256)
    Number a,b;

    cin>>equationArray;
    char* operatorPtr=getOperatorIndex(equationArray);

    a.lastPtr()=toIntArray(equationArray, operatorPtr, a.firstPtr());
    b.lastPtr()=toIntArray(operatorPtr+1, operatorPtr+strlen(operatorPtr), b.firstPtr());

    a.print();
    b.print();

    Number c;
    switch(*operatorPtr){
        case '-':
            c=a-b; 
            break;
    }
    c.print();

}


char* getOperatorIndex(char* equationString){
    while(!isOperator(*++equationString));   
    return equationString;
}

bool isOperator(char characterDec){
    if(characterDec>='*' & characterDec<='/')return true;
    return false;
}


int* toIntArray(char* firstInA, char* lastInA, int* firstInB){
    while(lastInA-firstInA>0){
        *firstInB=*firstInA-'0';
        ++firstInB;
        ++firstInA;
    }
    return --firstInB;  
}

【问题讨论】:

  • 你试过运行这个程序吗?老实说,我也不确定如果你复制构造具有动态分配数组的东西会发生什么。
  • 您能否澄清您的问题 - 为什么您认为数组成员变量与非数组成员变量不同?
  • 我们可以将您的类定义视为 typedef(如果它没有静态成员变量)和 type 它不分配内存。
  • @OliverCharlesworth,因为我有一个更大的程序可以准确地处理这种情况:在某些时候,返回的数组的行为与预期的读取一样,但是当我尝试写一些东西时,它会给出垃圾值。
  • @MikeMike,你能提供重现这种行为的代码吗?

标签: c++


【解决方案1】:

类的所有数据成员具有与创建的类对象相同的存储持续时间。因此在:

int main(){
   Arr temp; 
   doSomething(temp);
}

int[10]; 类型的数据成员 temp.arr 也具有自动存储持续时间..(或不恰当地称为“堆栈对象”)


Arr doSomething(Arr &arg){
   return arg; //copy of arg created; 'copy=new int[10]' at this point?
}

不,这里没有堆分配。而是由隐式复制构造函数进行的成员复制。见How are C++ array members handled in copy control functions?

【讨论】:

  • 如果有一个指针作为成员变量,它将指向数组中的最后一个元素?会不会导致临时对象被释放时,数组中的指针变量也会被释放?
  • @MikeMike,如果有指针,那么我们可以假设您的该类的对象管理资源。在这种情况下,您应该明确定义和实现您的特殊成员函数。这是因为,隐式复制构造函数只会复制指针的值,指针仍然会指向 old 对象数组的最后一个元素。现在的问题是新复制的指针数据成员没有指向它自己对象的数组的末尾,而是另一个对象。
  • @Mike Mike - 不。当包含指针的临时对象被释放或以其他方式销毁时,默认情况下指针不受影响。可以为对象的类编写一个析构函数,显式地用指针做一些事情,但这需要程序员有意识地采取行动。 C++ 不会被垃圾回收。
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2017-03-22
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多