包含指向堆分配内存的指针的 c 结构的按值调用

Call-by-value of a c struct containing a pointer to heap allocated memory

亲爱的Whosebugers。

在尝试使用 c 和结构的过程中,我和我的一个朋友遇到了一些我们无法完全理解的事情。下面是一个代码片段,描述了一个带有 int 指针和变量的结构。它们都是在主函数中创建结构时设置的。

我们想知道 c 如何处理结构上的按值调用。 Call-by-reference 是清晰、简单的引用,所有被修改的东西都会改变。现在奇怪或有趣的是按值调用。该结构被复制为局部变量,结构中的指针和长度值也是如此。基本上创建另一个指向同一堆内存的指针。 (如果我错了请纠正我)。

不,如果你释放这个指针会怎么样。这是否意味着您丢失了那里的信息?不一定,因为信息可能仍然存在于您的页面中。但是,如果您再次 malloc 指针怎么办。

为什么信息还在?使用和不使用新的 malloc。这不是说 OS 给了你一块新的内存吗?为什么那个值还在?如果传递带有指向堆内存的指针的按值调用结构,通常会发生什么情况?

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

typedef struct Struct
{
  int* array;
  int length;
} Struct;

void callByValue(Struct st)
{
  st.array[1] = 11;
  st.length = 11;

  /* This is weird */
  free(st. array);
}

void callByRef(Struct *st)
{
  st->array[1] = 22;
  st->length = 22;
}

int main()
{
  Struct s;
  s.array = malloc(2*sizeof(int));
  s.array[1] = 0;
  s.length = 0;

  printf("Before array[1]: %d length: %d\n", s.array[1], s.length);

  callByValue(s);

  printf("Caal-by-value array[1]: %d length: %d\n", s.array[1], s.length);

  callByRef(&s);

  printf("Caal-by-reference array[1]: %d length: %d\n", s.array[1], s.length);

  return 0;
}

输出

Before array[1]: 0 length: 0
Caal-by-value array[1]: 11 length: 0
Caal-by-reference array[1]: 22 length: 22

当您按值调用时,代码会复制该结构供函数使用。所以你有这种情况

main:        s.array  ---+
                         +---> MemA (memory for 2 ints)
callByValue: st.array ---+

在你 free(st.array) 之后,两个指针都无效,因为 MemA 已被释放。

malloc(1000...)之后,你有这种情况

main:        s.array  ---> MemA (invalid pointer)
callByValue: st.array ---> MemB (memory for 1000 ints)

main 中的指针没有得到更新并且仍然无效。在 main 中使用指针将导致未定义的行为。