动态内存访问仅在函数内部工作。

动态内存访问仅在函数内部工作。

此问题用于此常见问题的标准复制:

我在一个函数中动态地分配数据,所有事情都运行良好,但只在分配发生的函数中。当我试图在函数之外使用相同的数据时,会出现崩溃或其他意外的程序行为。

这里有一个MCVE:

#include <stdlib.h>#include <stdio.h>void create_array (int* data, int size){
  data = malloc(sizeof(*data) * size);
  for(int i=0; i<size; i++)
  {
    data[i] = i;
  }

  print_array(data, size);}void print_array (int* data, int size){
  for(int i=0; i<size; i++)
  {
    printf("%d ", data[i]);
  }
  printf("\n");}int main (void){
  int* data;
  const int size = 5;

  create_array(data, size);
  print_array(data, size);  // crash here

  free(data);}

什么时候都行print_array从内部调用create_array函数,我得到了预期的输出。0 1 2 3 4,但当我从main我的程序崩溃了。

原因是什么?


慕的地6264312
浏览 316回答 1
1回答

莫回无

这个错误的原因是data被create_array函数是只存在于该函数中的局部变量。从malloc仅存储在此局部变量中,从未返回给调用方。考虑这个简单的例子:void&nbsp;func&nbsp;(int&nbsp;x){ &nbsp;&nbsp;x&nbsp;=&nbsp;1; &nbsp;&nbsp;printf("%d",&nbsp;x);}...int&nbsp;a;func(a);printf("%d",&nbsp;a);&nbsp;//&nbsp;bad,&nbsp;undefined&nbsp;behavior&nbsp;-&nbsp;the&nbsp;program&nbsp;might&nbsp;crash&nbsp;or&nbsp;print&nbsp;garbage在这里,一个复制变量的a作为参数存储在函数中。x..这被称为按值传递.什么时候x被修改,只更改局部变量。变量a在调用方中保持不变,并且由于a如果没有初始化,它将包含“垃圾”,并且无法可靠地使用。指针也不例外这个按值传递的规则。在您的示例中,指针变量data按值传递给函数。这个data函数内的指针是一个本地副本,并从malloc永远不会被传回给打电话的人。因此调用方中的指针变量仍未初始化,因此程序崩溃。此外,create_array函数还创建了一个内存泄漏,因为在函数执行之后,程序中不再有任何指针来跟踪分配的内存块。有两种方法可以修改函数以按预期工作。通过将局部变量的副本返回给调用方:int*&nbsp;create_array&nbsp;(int&nbsp;size){ &nbsp;&nbsp;int*&nbsp;data&nbsp;=&nbsp;malloc(sizeof(*data)&nbsp;*&nbsp;size); &nbsp;&nbsp;for(int&nbsp;i=0;&nbsp;i<size;&nbsp;i++) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;data[i]&nbsp;=&nbsp;i; &nbsp;&nbsp;} &nbsp;&nbsp;print_array(data,&nbsp;size); &nbsp;&nbsp;return&nbsp;data;}int&nbsp;main&nbsp;(void){ &nbsp;&nbsp;int*&nbsp;data; &nbsp;&nbsp;const&nbsp;int&nbsp;size&nbsp;=&nbsp;5; &nbsp;&nbsp;data&nbsp;=&nbsp;create_array(size); &nbsp;&nbsp;print_array(data,&nbsp;size);}或者将地址传递给调用者的指针变量并直接写入调用者变量:void&nbsp;create_array&nbsp;(int**&nbsp;data,&nbsp;int&nbsp;size){ &nbsp;&nbsp;int*&nbsp;tmp&nbsp;=&nbsp;malloc(sizeof(*tmp)&nbsp;*&nbsp;size); &nbsp;&nbsp;for(int&nbsp;i=0;&nbsp;i<size;&nbsp;i++) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;tmp[i]&nbsp;=&nbsp;i; &nbsp;&nbsp;} &nbsp;&nbsp;*data&nbsp;=&nbsp;tmp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;print_array(*data,&nbsp;size);}int&nbsp;main&nbsp;(void){ &nbsp;&nbsp;int*&nbsp;data; &nbsp;&nbsp;const&nbsp;int&nbsp;size&nbsp;=&nbsp;5; &nbsp;&nbsp;create_array(&data,&nbsp;size); &nbsp;&nbsp;print_array(data,&nbsp;size);}两种形式都行。
打开App,查看更多内容
随时随地看视频慕课网APP