【问题标题】:Array memory Allocation doesn't work数组内存分配不起作用
【发布时间】:2013-05-16 13:56:54
【问题描述】:

我有下一堂课:

class A {
};

class B : public A {
  int num;
};

我主要有:

int main() {
    A* vec; // A is a class with pure virtual functions
    vec = new B[2]; // want to create a vector of B
}

vec[0] 定义正确,但 vec[1] 为 NULL。为什么它没有给我分配合适的内存?

我不想改变主线。让它工作。

(我知道我可以将 main 更改为:B* vec = new B[2] 但我不想)

任何帮助表示赞赏!

【问题讨论】:

标签: c++ memory-management polymorphism pointer-arithmetic


【解决方案1】:

您不能多态地处理数组,C++ 语言不支持它。表达式vec[x] 使用指针算法来确定元素的位置。如果您通过基类指针访问它,那么如果对象的大小以任何方式发生变化,它将无法正常工作。

例如,您的基类大小为 4 个字节,子类大小为 8 个字节。

base *a = new child[4];

当您访问a[1] 时,编译器会使用基类的大小来计算偏移量。在这种情况下,偏移量是 4 个字节,最终指向第一个元素的中间。

我建议使用带有适当智能指针的std::vectorstd::array 指针。

// For arrays that needs to be resized (requires delete for each new)
std::vector<A*> vec(5, NULL);
for(int i = 0; i < vec.size(); i++)
{
    vec[i] = new B();
}

// for arrays that are fixed in size (requires delete for each new)
std::array<A*, 5> vec;
for(int i = 0; i < vec.size(); i++)
{
    vec[i] = new B();
}

// for arrays that are fixed in size with smart pointers
// no delete needed 
std::array<std::unique_ptr<A>, 5> vec;
for(int i = 0; i < vec.size(); i++)
{
    vec[i].reset(new B());
}

【讨论】:

  • 你不能只做 B* vec_cp = new B[2]; memcpy(vec,vec_cp,sizeof(vec_cp))?通过直接对内存进行操作,可以绕过IMO这个限制。
  • 仅仅因为对象正确地存在于内存中并不意味着指针算法会成功。在这种情况下,vec 指针仍将被破坏,并且 vec[2] 仍将指向内存中稍后的一个字节,而不是稍后绑定到第二个 B 对象的适当的 8 个字节。
  • @georgesl B 可以隐式转换为A,因此您的 memcpy 与普通的旧赋值相同。你仍然会遇到同样的问题。
  • @CaptainObvlious,谢谢!对于代码: A vec*[5] = new B*[5];它会给我分配一个 1*5 的矩阵,对吧?
  • @AlonShmiel 是的,括号内的数字指定要分配的元素数量。在这种情况下,它是一个包含 5 个指针的数组,用于键入 A 类型的对象。
【解决方案2】:

如果你希望它是多态的,只需创建一个指针数组

new A*[array_size]

【讨论】:

    【解决方案3】:

    此代码 sn-p 说明了您遇到的问题。

    #include <iostream>
    using namespace std;
    class A {
    };
    
    class B : public A {
      int num;
    };
    
    int main() {
        A* vec; // A is a class with pure virtual functions
        vec = new B[2]; // want to create a vector of B
    
        cout << sizeof(vec) << endl;
        cout << sizeof(*vec) << endl;
        cout << sizeof(vec[2]) << endl;
        cout << sizeof(new B()) << endl;
    }
    

    在指针算法中,您分配的指针类型的大小用于递增,而不是它指向的对象的真实类型的大小。更简单地说,该语言不支持多态数组。这只是对原因的解释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 2014-03-14
      • 2012-03-23
      • 2011-12-15
      • 2021-04-02
      • 1970-01-01
      • 2020-08-18
      相关资源
      最近更新 更多