c++ 没有将某些数组元素设置为 nullptr

c++ doesn't set some of the array elements to nullptr

我在 int main() 内部声明了 double* arr = new double[2];(一个数组,其项目应设置为双倍或无)

然后我尝试从另一个函数 void func(double* arr_pointer[2]) 更改数组元素的值,方法是将它们设置为

arr_pointer[1] = nullptr;
arr_pointer[0] = nullptr;

但是在我通过打印

检查它们的值何时更改为nullptr(在主函数中)之后

cout << (nullptr == &arr[0]) << ' ' << (nullptr == &arr[1])

我在控制台中得到 1 0, 为什么?

最小可重现示例:

#include <iostream>

void func(double* arr_pointer[2], double& abc) {
    if (abc > 0) {
        (*arr_pointer)[0] = 20;
        (*arr_pointer)[1] = 22;
    }
    else if (abc == 0) {
        (*arr_pointer)[0] = 10;
        arr_pointer[1] = nullptr;
    }
    else {
        arr_pointer[1] = nullptr;
        arr_pointer[0] = nullptr;
    }
}

int main() {
    double* arr = new double[2];
    double abc = -1.2;
    func(&arr, abc)
    std::cout << (nullptr == &arr[0]) << ' ' << (nullptr == &arr[1])
}
double* arr = new double[2];

(an array that its items should be set to double or to nothing)

arr 是指向 double 的指针。它指向 2 个双精度数组的第一个元素。元素是双重对象;它们不能是“无”对象。此外,该数组不包含任何指针。

旁注:避免拥有裸指针。更喜欢使用 std::vector.

void func(double* arr_pointer[2])

数组类型的函数参数调整为指向该数组元素的指针。这个函数的参数是 double** 即指向 double.

的指针

您将无法调用 func(arr),因为 double* 不能隐式转换为 double**

cout << (nullptr == &arr[0]) << ' ' << (nullptr == &arr[1])

您正在将数组元素的地址与 null 进行比较。除非您在初始化后修改了 arr,否则这两个元素的地址都不应等于 null。


关于您的编辑:

func(&arr, abc)

arr 是一个单指针对象。它不是多个指针数组中的一个元素。

arr_pointer[1] = nullptr;

arr_pointer[1] 指向 arr 对象的末尾,并且分配给它会导致未定义的行为。如果程序的输出出乎您的意料,可能是因为程序的行为未定义。如果程序是您 do 所期望的,它可能是尽管行为未定义。不要这样做。

arr_pointer[0] = nullptr;

由于arr_pointer指向arr,通过arr_pointer间接寻址并赋值会导致arr被赋值。换句话说,这会将 arr 设置为指向 null。由于 arr 是指向动态数组的唯一指针,这意味着分配不能再被释放;这是内存泄漏。

在此赋值之后,是否允许 &arr[0] 值得怀疑,因为该下标运算符将通过空指针进行间接寻址。但是,如果我们假设它是允许的,那么 arr == nullptr 暗示 &arr[0] == nullptr.

是合理的

注意参数double* arr_pointer[2]不是两个指针的数组,它是指向double的指针的指针;它相当于 double** arr_pointer.
(您不能将数组传递给函数;[] 表示法只是向人类提示 reader 参数应该是一个数组。)

您的代码具有未定义的行为,因此它可以输出任何内容。
也许这可以通过内联函数得到最好的解释:

int main() {
    double* arr = new double[2];
    double abc = -1.2;

    double** arr_pointer = &arr;
    // Now, *arr_pointer, a.k.a. arr_pointer[0], is the same as arr
    // and *(arr_pointer + 1), a.k.a arr_pointer[1], does not exist.
    // It is undefined to dereference arr_pointer + 1.
    
    if (abc > 0) {
        (*arr_pointer)[0] = 20; // arr[0] = 20
        (*arr_pointer)[1] = 22; // arr[1] = 20
    }
    else if (abc == 0) {
        (*arr_pointer)[0] = 10; // arr[0] = 10
        arr_pointer[1] = nullptr; // arr_pointer[1] does not exist - undefined
    }
    else {
        arr_pointer[1] = nullptr; // arr_pointer[1] does not exist - undefined
        arr_pointer[0] = nullptr; // arr = nullptr
    }
    
    std::cout << (nullptr == &arr[0]) << ' ' << (nullptr == &arr[1])
}