【问题标题】:why array size information is available to `sizeof` operator and delete[] operator, but not when passing array as an argument into function [duplicate]为什么`sizeof`运算符和delete []运算符可以使用数组大小​​信息,但在将数组作为参数传递给函数时不可用[重复]
【发布时间】:2020-06-19 01:57:12
【问题描述】:

我想知道sizeof 运算符和delete[] 如何知道他们正在操作的数组的实际大小,但是当我将数组作为参数传递给函数时,大小信息会丢失,并且大小信息需要程序员显式传入函数吗?

导致这种差异的内部机制是什么?

#include <iostream>

void my_function(int* p, int n) {
    std::cout << "when passed into a function as argument, array size information is not available" << std::endl;
}

int main() {

    int a[] = { 1, 2, 3 };
    std::cout << "sizeof(a): " << sizeof(a) << std::endl; // size information available to `sizeof` operator

    int* b = new int[3] {1, 2, 3};
    delete[] b; //size information available to `delete[]` operator

    int c[] = { 1, 2, 3 };
    my_function(c, 3);

    return 0;
}

【问题讨论】:

  • 是什么让您认为代码中b 指针的“大小信息可用”?它可能(必须)内部对系统的内存分配器可用,但尝试显示一些代码,您可以在其中从指针本身获取b数组的大小solely (例如,如果您将 that 指针传递给另一个函数)。
  • 我的意思可能还没有完全说清楚,在使用delete[]的时候,数组大小信息对程序员是不可用的,但是delete[]可以使用,delete[]可以这样释放分配给数组的内存,对吧?
  • 是的!就像malloc 返回的指针一样(它甚至可以用于实现new[] 运算符)。对于您的 C++ 代码,它只是一个地址;对于系统来说,它是一个地址,它在某处/以某种方式被索引到系统范围内存管理器的已分配块列表中。
  • 所以delete[] 运算符可以使用大小信息,但为什么不能为作为参数传递给函数的数组提供相同的信息?
  • delete[] 运算符可用。它可用于该运算符的特定于系统的实现。 C++ 中的指针只是 一个地址。将这样的指针传递给函数不会向该函数传达有关数据块大小的任何信息,无论该指针来自new[]malloc 还是用户声明的固定数组的地址。它仍然只是一个指针。

标签: c++ arrays


【解决方案1】:

delete[] 运算符知道多少内存与特定指针值相关联的原因是,它在使用new[] 时写入的内部数据结构中保存了该值的副本。从严格的语言角度来看,它不知道指针指向多少内存。

还要求delete[] 的指针传递必须已由new[] 返回。传入任何其他指针值都会导致 undefined behavior

sizeof 运算符仅查看其操作数的类型,因此在编译时进行评估。在您的代码中,sizeof 运算符可以看到其操作数的类型为 int[3],并计算为数组的字节大小(大多数系统上为 12)。

当您将数组传递给函数时,它衰减为指向数组第一个元素的指针。所以在my_function 你只有一个指针。你可以很容易地做这样的事情:

int x;
my_function(&x, 1);

因此,如果您要在参数 p 上使用 sizeof,它会查看操作数的类型 int * 并计算指针的大小(很可能是 4 或 8)。

【讨论】:

  • 只是想知道,为什么他们不能将“保存在其内部数据结构中的值的副本”提供给程序员?
  • @Thor 根据库,它可能可用。在 Linux 上,有一个名为 malloc_usable_size 的函数,它返回 malloc 指针指向的字节数。然而,类似的东西是非常系统特定的。
  • @Thor 松散的代词失去了理解。 ;) 当您撰写该评论时,您是否清楚地了解“他们”是谁?在这种情况下,“他们”表示编写 C++ 规范的人与“他们”表示在特定系统上实现 C++ 的人之间存在巨大差异。
猜你喜欢
  • 2017-05-28
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-23
  • 2012-11-10
相关资源
最近更新 更多