将指针指定给函数或将其地址作为函数参数传递之间有什么区别吗?

时间:2016-03-22 14:42:52

标签: c pointers malloc

我真的不知道如何更恰当地问它,但我会尝试解释我的问题。

假设我们有以下内容:

int *ptr = foo(&ptr);

这对我来说,我相信这意味着,函数declaration中有initialization foo,其指针自己用作函数参数。

现在以下内容:

int *ptr = foo();

我认为是相同的,但是没有任何函数参数,这意味着函数foo不会接受任何参数。

现在让我们来看看以下两个程序:

计划1:

#include <stdio.h>
#include <stdlib.h>

#define SIZE 3

int *foo(int **ptr);

int main(void){
    int *ptr = foo(&ptr);

    for (int i=0 ; i<SIZE ; i++){
        *(ptr + i) = i + 1;
    }

    for (int j=0 ; j<SIZE ; j++){
        printf("%d\n",*(ptr + j));
    }

    free(ptr);
}

int *foo(int **ptr){
    *ptr = malloc(SIZE * sizeof(*ptr));
    if(*ptr == NULL){
        printf("Error, malloc\n");
        exit(1);
    }
    return *ptr;
}

计划2:

#include <stdio.h>
#include <stdlib.h>

#define SIZE 3

int *foo(void);

int main(void){
    int *ptr = foo();

    for (int i=0 ; i<SIZE ; i++){
        *(ptr + i) = i + 1;
    }

    for (int j=0 ; j<SIZE ; j++){
        printf("%d\n",*(ptr + j));
    }

    free(ptr);
}

int *foo(void){
    int *ptr = malloc(SIZE * sizeof(*ptr));

    if(ptr == NULL){
        printf("Error, malloc\ņ");
        exit(1);
    }
    return ptr;
}

program 1program 2的差异/好处是什么。

第一个或第二个程序中的指针是否有某种不同的影响?或者是否有任何理由使用program 1program 2

我问,因为编程行为的方式看起来program 1program 2是相同的。

编辑: 我知道第一个程序的指针ptrfoo函数修改,在第二个程序中我在函数foo中声明它,但这不是我的问题。

2 个答案:

答案 0 :(得分:2)

程序之间唯一的实际区别在于第一个可以分配比第二个更多的内存量。

在第一个程序中,您使用*ptr来获取大小,但*ptr的类型为int *,在64位系统上通常为64位。在第二个程序中,*ptrint,并且32位和64位系统上int的大小通常为32位。

由于第一个程序模拟通过引用传递,你可以在不使用返回指针的情况下使用它,事实上它根本不需要返回一个值,并且可以声明为返回void。哪一个是首选是个人选择,我个人更喜欢第二种选择,但它也取决于用例。

答案 1 :(得分:2)

在第一个程序中,您分配SIZE * sizeof(int *)个字节,并将该内存用作SIZE * sizeof(int)长的内存。这意味着,如果你有sizeof(int *)&lt; sizeof(int)你会在缓冲区溢出中运行。

另一个问题是,在int *ptr = foo(&ptr);中,您在一个表达式中修改变量ptr两次,这很糟糕,因为您无法知道哪一个首先出现。但正如你通常写相同的值,这里应该没问题。

另一个区别是,在第一个程序中,如果在调用ptr之前分配错误,则将exit()的值设置为NULL,而在第二个程序中,变量保持未初始化。但是在这种情况下使用exit时,ptr变量会立即消失,即使在atexit注册函数中也无法使用。

恕我直言,您使用*ptr = malloc(SIZE * sizeof(int));*ptr = malloc(SIZE * sizeof(**ptr));修复了第一个程序,2个版本的行为相同。