修改返回函数的内存地址内容

时间:2019-01-25 14:36:23

标签: c return-value

是否可以修改函数返回值的内存地址的内容?函数返回本地定义变量的值。

在以下示例中,为我的机器(x86-64)编译时没有警告:

#include <stdio.h>

int get_val1()
{
  int ret = 1;
  return ret;
}

int get_val2()
{
  int ret = 2;
  return ret;
}

int get_val3()
{
  int ret = 3;
  return ret;
}

void redefine_ints(int *val1, int *val2, int *val3) {
  *val1 = 10;
  *val2 = 11;
  *val3 = 12;
}

void print_and_redefine_ints(int val1, int val2, int val3) {
  printf("val1 %d val2 %d val3 %d\n", val1, val2, val3);
  redefine_ints(&val1, &val2, &val3);
  printf("rval1 %d rval2 %d rval3 %d\n", val1, val2, val3);
}

int main()
{
  print_and_redefine_ints(get_val1(), get_val2(), get_val3());
  return 0;
}

我得到下一个输出:

val1 1 val2 2 val3 3
rval1 10 rval2 11 rval3 12

这是预期的输出,但是怎么可能呢?这些变量存储在哪里?

3 个答案:

答案 0 :(得分:5)

是的,这是定义明确的C。

int创建的匿名临时 get_val...()的生存期与创建它们的整个语句相同。

但是请注意,在致电int时,您需要对这print_and_redefine_ints中的每一个进行复制,所以这里没有什么特别的事情。

(请注意,您将无法将指向匿名临时int的指针 绑定到int*函数参数。)

答案 1 :(得分:4)

平局可能不仅仅解释一些文字。在该示例中,我将仅使用1 get_val1()

print_and_redefine_ints(get_val1());
                           |
                           |
                         [CALL]
                           |
                           |
                           V
                    int get_val1()
                    {
                        int ret = 1;<----------------------------------------------------+
                        return ret;                                                      |
                    }      |                                                             |
                           |                                                             |
                    [COPY OF VALUE]                                                      |
                           |                                                             |
                           |                                                             |
                           +---+                                                         |
                               |                                                         |
                               |                                                         |
                               V                                                         |
void print_and_redefine_ints(int val1) {                                                 |
    printf("val1 %d\n");        ^                                                        |
    redefine_ints(&val1);       |                                                        |
                    |           +--------------------------------------------+           |
                    |                                                        |           |
          [POINTER AKA REFERENCE]                                            |           |
                    |                                                        |           |
                     |                                                       |           |
                      V                                                      |           |
void redefine_ints(int *val1) {                                              |           |
    *val1 = 10; //<---- the value is changed, then its referenced value (this one, NOT THIS ONE) is changed too
}                     |
                      |
                      +---+
                          |
                    [VALUE CHANGED]
                          |
                          |
                          V
    printf("rval1 %d\n", val1);
    printf("original val1 %d\n", get_val1()); //if you add this line, you'll notice the returned value of get_val1() is still 1
}

答案 2 :(得分:3)

  

是否可以修改函数返回值(值)的内存地址内容?

不,不是。

但是,此处并非如此。在您的代码中,get_val<n>()函数调用的返回值存储在函数参数int val1int val2int val3中。它们是被调用函数的本地函数。这些变量的生命周期就是函数执行周期。

引用C11,第6.2.1章,

  

[...]如果声明符或类型说明符   声明标识符出现在一个块内或其中的参数声明列表中   函数定义,标识符具有块作用域,该作用域终止于   关联的块。 [....]

以及第6.9.1节中的函数定义

  

每个参数都有自动存储时间;它的标识符是左值

因此,就像其他任何局部变量一样,您可以使用它们的地址来修改这些变量的内容。