为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C
慕的地6264312 2019-06-15 18:14:05
动态内存访问仅在函数内部工作。此问题用于此常见问题的标准复制:我在一个函数中动态地分配数据,所有事情都运行良好,但只在分配发生的函数中。当我试图在函数之外使用相同的数据时,会出现崩溃或其他意外的程序行为。这里有一个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我的程序崩溃了。原因是什么?
查看完整描述

1 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

这个错误的原因是datacreate_array函数是只存在于该函数中的局部变量。从malloc仅存储在此局部变量中,从未返回给调用方。


考虑这个简单的例子:

void func (int x){
  x = 1;
  printf("%d", x);}...int a;func(a);printf("%d", a); // bad, undefined behavior - the program might crash or print garbage

在这里,一个复制变量的a作为参数存储在函数中。x..这被称为按值传递.

什么时候x被修改,只更改局部变量。变量a在调用方中保持不变,并且由于a如果没有初始化,它将包含“垃圾”,并且无法可靠地使用。


指针也不例外这个按值传递的规则。在您的示例中,指针变量data按值传递给函数。这个data函数内的指针是一个本地副本,并从malloc永远不会被传回给打电话的人。

因此调用方中的指针变量仍未初始化,因此程序崩溃。此外,create_array函数还创建了一个内存泄漏,因为在函数执行之后,程序中不再有任何指针来跟踪分配的内存块。


有两种方法可以修改函数以按预期工作。通过将局部变量的副本返回给调用方:

int* create_array (int size){
  int* data = malloc(sizeof(*data) * size);
  for(int i=0; i<size; i++)
  {
    data[i] = i;
  }

  print_array(data, size);

  return data;}int main (void){
  int* data;
  const int size = 5;

  data = create_array(size);
  print_array(data, size);}

或者将地址传递给调用者的指针变量并直接写入调用者变量:

void create_array (int** data, int size){
  int* tmp = malloc(sizeof(*tmp) * size);
  for(int i=0; i<size; i++)
  {
    tmp[i] = i;
  }

  *data = tmp;      
  print_array(*data, size);}int main (void){
  int* data;
  const int size = 5;

  create_array(&data, size);
  print_array(data, size);}

两种形式都行。


查看完整回答
反对 回复 2019-06-15
  • 1 回答
  • 0 关注
  • 315 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信