简体   繁体   English

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

[英]Is there any difference between assigning the pointer to the function or passing its address as function argument?

I really don't know how to ask it more properly, but I will try to explain my problem. 我真的不知道如何更恰当地提出问题,但是我将尽力解释我的问题。

Lets say we have the following: 可以说我们有以下内容:

int *ptr = foo(&ptr);

This for me I believe it means that, there is a declaration with initialization to the function foo with the pointer it self used as function argument. 对于我来说,我相信这意味着,有一个declaration initializationfoo函数,并将其自身用作函数参数的指针。

Now the following: 现在,以下内容:

int *ptr = foo();

I think is the same, but without any function argument, which means that, the function foo doesn't take any arguments. 我认为是相同的,但是没有任何函数参数,这意味着函数foo不带任何参数。

Now lets take a look at the following two programs: 现在,让我们看一下以下两个程序:

Program 1: 程序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;
}

Program 2: 程式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;
}

What is the differences/benefits of program 1 or program 2 . program 1program 2的区别/好处是什么?

Is the pointer in the first or second program somehow different affected? 第一个或第二个程序中的指针是否会受到不同的影响? Or is there any reason of using program 1 or program 2 ? 还是有使用program 1program 2任何理由?

I'm asking, because the way how to program behaves looks that program 1 and program 2 are the same. 我在问,因为程序编程的方式看起来program 1program 2相同。

EDIT: I know that the fist program has the pointer ptr modified by the foo function and in the second one I declare it inside the Function foo , but this is not my Question. 编辑:我知道第一个程序具有由foo函数修改的指针ptr ,在第二个程序中,我在Function foo内部声明了它,但这不是我的问题。

The only practical difference between the programs is that the first one could allocate double the amount of memory compared to the second. 程序之间的唯一实际区别是,第一个程序分配的内存量是第二个程序的两倍。

In the first program you use *ptr to get the size, but *ptr is of type int * which on a 64-bit system is usually 64 bits. 在第一个程序中,您使用*ptr来获取大小,但是*ptr的类型为int * ,在64位系统上通常为64位。 In the second program *ptr is an int and the size of an int is usually 32 bits on both 32 and 64 bit systems. 在第二个方案*ptrint和一个大小int通常是在32个和64位系统的32位。

Since the first program emulates passing by reference, you could use it without using the returned pointer, and in fact it doesn't have to return a value at all and could be declared as returning void . 由于第一个程序模拟了按引用传递,因此您可以不使用返回的指针就使用它,实际上,它根本不必返回任何值,并且可以声明为return void Which one is preferred is a personal choice, I personally prefer the second alternative, but it also depends on use-case. 哪个是首选是个人选择,我个人更喜欢第二种选择,但这还取决于用例。

In first program, you alloc SIZE * sizeof(int *) bytes, and use that memory as if it was SIZE * sizeof(int) long. 在第一个程序中,您分配SIZE * sizeof(int *)个字节,并像使用SIZE * sizeof(int)长一样使用该内存。 That means that if you had sizeof(int *) < sizeof(int) you would run in a buffer overflow. 这意味着,如果您的sizeof(int *) < sizeof(int)您将在缓冲区溢出中运行。

Another problem is that in int *ptr = foo(&ptr); 另一个问题是int *ptr = foo(&ptr); you are modifying the variable ptr twice in one single expression, which is bad because you cannot know which one occurs first. 您在一个表达式中修改了变量ptr两次,这很糟糕,因为您不知道哪个变量最先出现。 But as you normally write same value it should be ok here. 但是,正如您通常写入相同的值一样,在这里应该没问题。

Another difference is that in first program, you set the value of ptr to NULL in case of allocation error before calling exit() , while in the second, the variable remains uninitialized. 另一个区别是,在第一个程序中,如果分配错误,则在调用exit()之前将ptr的值设置为NULL,而在第二个程序中,变量保持未初始化。 But as you use exit in that case, the ptr variable immediately vanishes and could not be used even in an atexit registered function. 但是,在这种情况下使用exit时,ptr变量立即消失,即使在atexit注册函数中也无法使用。

IMHO provided you fix first program by using *ptr = malloc(SIZE * sizeof(int)); 恕我直言,前提是您使用*ptr = malloc(SIZE * sizeof(int));修复了第一个程序*ptr = malloc(SIZE * sizeof(int)); or *ptr = malloc(SIZE * sizeof(**ptr)); *ptr = malloc(SIZE * sizeof(**ptr)); , the 2 versions behave the same. ,这两个版本的行为相同。

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

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