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

时间:2018-01-29 04:36:53

标签: c++ arrays pointers

如果我写int* a = new int[5];,然后拨打sizeof(a)sizeof(*a),我就无法获取所需的信息,因为数组已经衰减为指针。但是,我想知道我们是否可以做这样的事情:

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

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

3 个答案:

答案 0 :(得分: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,显示函数外部和内部的大小相同(它也是元素中的大小而不是给定的字节{{1}前者通常是一个更有用的措施。)

在指导或培训C ++程序员时,我总是警告他们成为&#34; C +&#34;程序员,一个在C上长大并且从未真正完全转换到C ++的东西(比如继续使用原始数组而不是向量,在标准库中使用sizeof完全适合的时候滚动自己的数据结构或malloc/free,等等。)

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

(a)有趣的是,你的具体问题有一个数组衰减成指针。 printf调用实际上直接返回指针,因此不会涉及衰减。

new

答案 1 :(得分:3)

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

  1. 将数组的大小与数组分开:std::vector<int> a(5); a.size()
  2. 使用C ++构造为您处理此问题:std::vector
  3. 我强烈推荐选项2.不仅仅是因为它更容易,delete[]提供更多功能。但是因为RAII风格的构造为你管理内存意味着你不需要记得以后在内存上调用delete。由于您可能忘记它是一个数组,因此您也不能在以后意外调用内存中的{{1}}。

答案 2 :(得分:-1)

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

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

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

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