繁体   English   中英

在堆上分配内存时防止数组衰减?

[英]Preventing array decay when allocating memory on the heap?

如果我写int* a = new int[5]; 然后我调用sizeof(a)sizeof(*a) ,我没有得到我想要的信息,因为数组已经衰减成指针。 但是,我想知道我们是否有办法做这样的事情:

int[5]* a = new int[5];

我很确定我们能够用堆栈内存做到这一点,但我不确定是否有任何方法可以为堆内存执行此操作,因为以上内容无法编译。 如果没有办法,有没有理由不这样做?

C ++最初只是C的前端,并且因此从原始语言中带来了相当多的包袱。 比如<cXXX>标题中的很多东西,以及许多操作的行为,比如数组衰减(a)

如果你想要一个更方便的数组类型,C ++在std::vector 这样的野兽。 如果你传递它,你将不会受到使用更低级别内存分配方法时可能看到的衰减的影响。 例如,见:

#include <iostream>
#include <vector>

void someFunction (const std::vector<int> &myVec) {
    std::cout << myVec.size() << std::endl;
}

int main() {
    std::vector<int> myVec({ 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9, 0 });
    std::cout << myVec.size() << ' ';
    someFunction(myVec);
}

它输出13 13 ,表明函数外部和内部的大小相同(它也是元素的大小而不是给定的bt sizeof字节,前者通常是一个更有用的度量)。


在指导或培训C ++程序员时,我总是警告他们成为一名“C +”程序员,一个在C语言中长大并且从未真正完全过渡到C ++的人(比如继续使用原始数组而不是向量,滚动自己的数据)当完全足够的结构在标准库中时,使用malloc/freeprintf等等)。

你会明智地将C和C ++视为相关但完全不同的语言,并尽可能采用C ++思维方式。


(a)中有趣的是,您的具体问题具有阵列衰变成一个指针。 new调用实际上直接返回一个指针,因此不会涉及衰减。

在哪里你看到衰变是这样的:

void someFunction (int x[]) {
    // Pointer to first element here, size is int-pointer-size.

    std::cout << sizeof(x) << std::endl;
}

:

// Array here, size is 13 * int-size.

int xyzzy[] = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9, 0 };
std::cout << sizeof(xyzzy) << std::endl;

someFunction(xyzzy);

无法将此信息存储在指针中。 并且没有单独的构造可以让您按照自己的方式执行此操作。 你的选择是:

  1. 将数组的大小与数组分开存储: const int a_size = 5; int *a = new int[a_size] const int a_size = 5; int *a = new int[a_size]
  2. 使用C ++构造为您处理: std::vector<int> a(5); a.size() std::vector<int> a(5); a.size()

我强烈推荐选项2.不仅仅是因为它更容易和std::vector提供更多功能。 但是因为RAII样式构造为你管理内存意味着你不需要记得以后在内存上调用delete[] 您也不能在以后意外调用内存中的delete ,因为您可能忘记它是一个数组。

当然,您可以通过二维数组,例如

int (*a)[5] = new int[1][5];

注意:此代码仅用于语言 - 律师目的,不建议在实践中使用。 如果这是一个XY问题,你应该使用std::vectorstd::array作为建议的其他答案

new int[N]返回指向其第一个元素的指针而不是像非数组new一样指向自身的指针的原因之一是使数组的使用更容易。 例如,使用auto a = new int[5] ,您可以通过简单的a[n]而不是(*a)[n]来访问数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM