简体   繁体   English

在函数中动态分配数组

[英]Dynamically allocate array in functions

So, I am new to c++ and I would like to know why the value doesn't get updated in the array.所以,我是 c++ 的新手,我想知道为什么数组中的值没有更新。 Can anybody please explain where I Did wrong.谁能解释一下我哪里做错了。 Would appreciate any commends.将不胜感激任何表扬。 when I try to execute it, it always returns 0 as in std::cout<<sum<<std::endl;当我尝试执行它时,它总是返回 0,如 std::cout<<sum<<std::endl; I try to see and I realize that my array doesn't get updated我试着看看,我意识到我的阵列没有得到更新

    #include <iostream>
    int sum_of_even(int* arr, int n)
    {
        int sum = 0;
        arr = new int[n];
        for(int i=0;i<n;i++)
        {
            if(arr[i] % 2==0)
            {
                sum += arr[i];
                std::cout<<sum<<std::endl;
            }
        }
        return sum;
    }
    int main()
    {
        int numbers[5] = {1,2,3,4,5};
        std::cout<<sum_of_even(numbers,5)<<std::endl;
    }

When arrays condense into pointers in a function parameter, it stores the addresses to the first element in the array.当 arrays 压缩成 function 参数中的指针时,它将地址存储到数组中的第一个元素。 Addresses are just locations in memory, and nothing more, they have nothing to do with their contents, so what this line does:地址只是 memory 中的位置,仅此而已,它们与其内容无关,所以这一行的作用是:

arr = new int[n];

This just makes the whole passing the pointer to the first element of the array useless since the first thing you do with the pointer is make it point to a different memory that was allocated using new[] that is completely unrelated to the array you pass to the function.这只会使整个将指针传递给数组的第一个元素变得毫无用处,因为您对指针所做的第一件事就是使其指向另一个 memory,它是使用new[]分配的,与您传递给的数组完全无关function。

Additionally, new[] will not magically initialize all your elements, so what you see are uninitialized/undefined values inside the dynamically allocated memory, and trying to read uninitialized values is Undefined Behavior in C++ because you can get any sort of value out of it.此外, new[]不会神奇地初始化所有元素,因此您看到的是动态分配的 memory 中未初始化/未定义的值,并且尝试读取未初始化的值是 C++ 中的未定义行为,因为您可以从中获取任何类型的值.

So you have to initialize the memory manually after allocating it:所以你必须在分配后手动初始化 memory :

#include <iostream>
#include <algorithm>

int sum_of_even(int* arr, int n)
{
    int sum = 0;
    int* const tmp = arr; // Store the pointer to the first element of the array temporarily as the line below will immediately replace it
    arr = new int[n];
    std::copy(tmp, tmp + n, arr); // Initialize the dynamically allocated memory with values inside 'arr'
    for(int i = 0; i < n; i++)
    {
        if(arr[i] % 2 == 0)
        {
            sum += arr[i];
            std::cout << sum << std::endl;
        }
    }
    delete[] arr; // You NEED to call `delete[]` after using `new[]` or say hello to memory leaks!
    return sum;
}

// ...

Or just get rid of the dynamic allocation entirely since it is not needed and adds needless overhead.或者完全摆脱动态分配,因为它不需要并且增加了不必要的开销。

Edit: It appears that you are trying to allocate at the address where the array is situated.编辑:看来您正在尝试在数组所在的地址进行分配。 You can do that using placement new :您可以使用placement new来做到这一点:

arr = new (arr) new int[n];

But this is kind of useless and isn't really needed in your case.但这有点没用,在您的情况下并不是真正需要的。

When calling sum_of_even() you provide the address of the first element of numbers as the parameter arr .调用sum_of_even()时,您提供numbers的第一个元素的地址作为参数arr

But then in sum_of_even() you replace this address with the result of new int[n] .但随后在sum_of_even()中,您将此地址替换为new int[n]的结果。

So you don't sum up the values of numbers .所以你不总结numbers的值。

You are passing the address of the array, not the array itself.您传递的是数组的地址,而不是数组本身。 You can see this if you add a debug statement printing the value of arr immediately inside sum_of_even.如果您在 sum_of_even 中添加一个调试语句,立即打印 arr 的值,您可以看到这一点。 You will see something like 0x7fff1c32e890 displayed.您将看到显示类似 0x7fff1c32e890 的内容。 This is the machine address where arr is stored.这是存储 arr 的机器地址。

Change sum_of_even to receive an array, not a pointer:更改 sum_of_even 以接收数组,而不是指针:

int sum_of_even(int arr[], int n)

and as previously mentioned, this line wipes out your entire array如前所述,此行会清除整个数组

arr = new int[n]

You are re-assigning the int* arr pointer to point to a different memory address created on the heap with new int[n] in this line:您正在重新分配int* arr指针以指向在该行中使用new int[n]在堆上创建的不同 memory 地址:

arr = new int[n];

You can see your code working as expected here when commenting out that line, which means you are not accessing the actual numbers array.注释掉该行时,您可以在此处看到您的代码按预期工作,这意味着您没有访问实际的numbers数组。

It is also good practice to indicate the intention of your function through using const when passing parameters.通过在传递参数时使用const来指示 function 的意图也是一种很好的做法。 Eg if you want to safely prevent the re-assigning of the pointer inside your function, thus indicating "read-only", use this example :例如,如果您想安全地防止在您的 function 中重新分配指针,从而指示“只读”,请使用此示例

// The order of const and the type int* matters here
int sum_of_even(int* const arr, int n)

/* Compiler error:
<source>: In function 'int sum_of_even(int*, int)':
<source>:5:13: error: assignment of read-only parameter 'arr'
         arr = new int[n]; */

As an added note.作为补充说明。 Your function creates a memory leak, due to not freeing the new int[n] array.由于未释放new int[n]数组,您的 function 会造成 memory 泄漏。 This is done through adding delete [] arr;这是通过添加delete [] arr;

I would also propose to solve your problem in a modern cpp way through using the containers and std functions available in the stl .我还建议通过使用stl中可用的容器和std函数以现代 cpp方式解决您的问题。

For example, rather add your numbers to a std::vector container and use std::accumulate in combination with a lambda to sum your even numbers as in this example :例如,而是将您的数字添加到std::vector容器中,并结合使用std::accumulate和 lambda 来对您的偶数求和,如本例所示

// Use a vector container for your data
std::vector<int> numbers{1, 2, 3, 4, 5};

// Create the sum with a combination of accumulate and a sum if even lambda
int sum = std::accumulate(numbers.begin(), 
                          numbers.end(),
                          0,  // Start with a sum of zero
                          [](int sum, int num) {
                           // Sum only on EVEN numbers
                           return num % 2 == 0 ? sum + num : sum;
                         });

You are declaring the array again in your function due to which the array you passed is not even being used in your function. An uninitialized array is being used in your function making your sum carry wrong value您在 function 中再次声明数组,因此您传递的数组甚至没有在您的 function 中使用。在您的 function 中使用了未初始化的数组,使您的总和值错误

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

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