复制指针和内存分配混乱 [英] copying pointers and memory allocation confusion

查看:67
本文介绍了复制指针和内存分配混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想创建一个接受数组并修改它的函数怎么办.

What if I want to make a function that takes in an array and modifies it.

void mod_Arr(int* arr) {
    int*arr = int[3][3]; //arr is now an array
    int*arrCpy = arr;
    //some modification to arrCpy
}

``

1) arr 也会被修改吗?即我必须包括以下行:arr = arrCpy;或者我应该改用:arr = mod_Arr(arr)//并获取 mod_Arr 返回一个数组?2)我是否必须释放(arr)以防止 arr 的旧值占用空间?如果指针现在指向新的内存而不是修改旧地址的值,我是否必须清理仍然在旧地址中的无用内容?

1) will arr be modified as well? i.e must I include the line: arr = arrCpy; or should I instead use: arr = mod_Arr(arr) //and get mod_Arr to return an array? 2) Must I free(arr) to prevent old values of arr taking up space? In the case that the pointer now points to a new memory instead of modifying the values at the old address, must I clean up the useless stuff still in the old address?

推荐答案

如果你在 main() 中有一个数组,它是 int a[3][3]; 并且您想将该数组传递给您的函数,以便可以在函数内修改它以及在调用函数中看到的更改(main() 此处),您必须传递的地址数组作为参数.如果您只是简单地按值传递数组本身,那么该函数会收到该数组的副本,并且当该函数执行该函数时,该函数中对该数组所做的任何更改都将丢失返回——就像任何其他本地声明的数组一样.

If you have an array in main() that is int a[3][3]; and you want to pass that array to your function such that it can be modified within the function and the changes seen back in the calling function (main() here), the you must pass the address of the array as the parameter. If you simply pass the array itself by-value, then the function receives a copy-of the array and any changes made to the array in the function are lost when the function returns -- just like any other locally declared array would be.

当你取一个数组的地址时,你就有了一个指向该数组的指针.在您的情况下,指向二维数组的指针.上述类型的语法为 int (*a)[3][3].(例如,int[3][3]pointer-to-array)所以要传递address-of 数组(它是仍然通过地址by-value,C 没有引用),你的函数声明看起来像:

When you take the address-of an array, you have a pointer to the array. In your case a pointer to a 2D array. The syntax for the type above would be int (*a)[3][3]. (e.g. a pointer-to-array of int[3][3]) So to pass the address-of the array (it is still passing the address by-value, C does not have references), your function declaration would look like:

void mod_arr (int (*a)[ROWS][COLS])
{
    for (int i = 0; i < ROWS; i++)
        for (int j = 0; j < COLS; j++)
            (*a)[i][j] = (i + 1) * (j + 1);
}

要在函数内对原始数组进行操作并分配/更改元素的值,您必须取消引用指向数组的指针.如果你看上面,那就是:

To operate on the original array within the function and assign/change the values of elements, you must dereference the pointer-to-array. If you look above, that would be:

            (*a)[i][j] = (i + 1) * (j + 1);

由于 C 运算符优先级.

声明一个简短的 prn_arr 函数来打印结果,您可以执行以下操作:

Declaring a short prn_arr function to print the results you could do something like the following:

#include <stdio.h>

#define ROWS 3
#define COLS ROWS

void mod_arr (int (*a)[ROWS][COLS])
{
    for (int i = 0; i < ROWS; i++)
        for (int j = 0; j < COLS; j++)
            (*a)[i][j] = (i + 1) * (j + 1);
}

void prn_arr (int a[ROWS][COLS])
{
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++)
            printf (" %2d", a[i][j]);
        putchar ('\n');
    }
}

int main (void) {

    int a[ROWS][COLS] = {{0}};

    mod_arr (&a);
    prn_arr (a);
}

在上面的 main() 中,您只需声明数组并将值初始化为零,然后将地址传递给 mod_arr 以操作数组,然后调用 prn_arr 输出结果——只需要传递数组本身(它是一个指向第一个 ROW 值的指针).

Where in main() above, you simply declare the array and initialize the values all zero and then pass the address to mod_arr for manipulation of the array, and then call prn_arr to output the results -- needing only to pass the array itself (it being a pointer to the first ROW of values).

但是,请记住,对于大型数组,将指向数组的指针作为参数传递比传递数组的完整副本更有效(例如,无论大小如何,指针在 x86_64 上都是 8 字节的数组,而以 1000x1000 的数组为例,它需要复制元素字节大小的 1,000,000 倍)

However, keep in mind for large arrays, it is more efficient to pass a pointer to the array as a parameter as opposed to passing a complete copy of the array (e.g. a pointer is 8-bytes on x86_64 regardless of the size of the array, while, take for example, a 1000x1000 array which would require 1,000,000 times the size of the element bytes to copy)

示例使用/输出

$ ./bin/modarr
  1  2  3
  2  4  6
  3  6  9

所以你可以看到,通过将数组按地址传递给你的函数,函数接收到数组的原始地址(而不仅仅是数组的副本作为一些新地址),所以在 mod_arr 是对原始数组本身内的地址所做的更改,并将在调用函数中看到.

So you can see, by passing the array by-address to your function, the function receives the original address for the array (and not merely a copy of the array as some new address), so the changes made in mod_arr are changes made to the addresses within the original array itself and will be seen back in the calling function.

检查一下,如果您还有其他问题,请告诉我.这是使用指针和数组时的一个核心问题——了解所涉及的类型以及这些类型的语法,使您能够使其全部工作.

Look things over and if you have further questions, let me know. This is kind of a core issue when working with pointers and arrays -- understanding the types involved and the syntax for those type that allow you to make it all work.

这篇关于复制指针和内存分配混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆