C 动态内存访问仅在功能内部工作

C 动态内存访问仅在功能内部工作,c,malloc,parameter-passing,dynamic-memory-allocation,pass-by-value,C,Malloc,Parameter Passing,Dynamic Memory Allocation,Pass By Value,此问题旨在用作此常见问题解答的标准副本: 我在一个函数中动态分配数据,一切都很好,但只在进行分配的函数中。当我试图在函数外使用相同的数据时,会出现崩溃或其他意外的程序行为 这是一个 #包括 #包括 无效创建_数组(整数*数据,整数大小) { 数据=malloc(sizeof(*数据)*大小); 对于(int i=0;i此错误的原因是create_array函数使用的数据是一个仅存在于该函数内部的局部变量。从malloc获得的分配内存地址仅存储在该局部变量中,不会返回给调用方 考虑这个简单的例子

此问题旨在用作此常见问题解答的标准副本:

我在一个函数中动态分配数据,一切都很好,但只在进行分配的函数中。当我试图在函数外使用相同的数据时,会出现崩溃或其他意外的程序行为

这是一个

#包括
#包括
无效创建_数组(整数*数据,整数大小)
{
数据=malloc(sizeof(*数据)*大小);

对于(int i=0;i此错误的原因是
create_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);
}
int*创建数组(int大小)
{
int*data=malloc(sizeof(*data)*大小);

对于(int i=0;i此错误的原因是
create_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);
}
int*创建数组(int大小)
{
int*data=malloc(sizeof(*data)*大小);

因为(inti=0;我几乎因为你犯了这么愚蠢的错误而否决了你:)让我想起弗兰Jo.OsFabRead不幸的是,我还没有找到一个方法来解决社区wiki问题,只是答案。我已经拨动了MODS,所以希望它很快就会转换成社区wiki。我认为可以更好地托管在文档beta版上。@ RestulcC0BRA假阳性=工具Bug =破碎工具。VS2015是C++编译器。它不符合C标准,也不符合1999年以前的C标准,也不符合古老的C90/ANSI标准。众所周知,抱怨完美的C代码也是众所周知的,因为微软认为只有他们才有权决定哪些语言功能是正确的好的和坏的,而不是C标准委员会。@Lundin如果可以的话,我会对你的评论给予奖励!我差点因为你犯了这么愚蠢的错误而否决了你:)让我想起弗兰Jo.OsFabRead不幸的是,我还没有找到一个方法来解决社区wiki问题,只是答案。我已经拨动了MODS,所以希望它很快就会转换成社区wiki。我认为可以更好地托管在文档beta版上。@ RestulcC0BRA假阳性=工具Bug =破碎工具。VS2015是C++编译器。它不符合C标准,也不符合1999年以前的C标准,也不符合古老的C90/ANSI标准。众所周知,抱怨完美的C代码也是众所周知的,因为微软认为只有他们才有权决定哪些语言功能是正确的好的和坏的,而不是C标准委员会。@Lundin如果可以的话,我会对你的评论给予奖励。@untinsic0bra谢谢,它已经被修复。虽然这是一个社区维基,所以你也可以自由编辑它。@untinsic0bra谢谢,它已经被修复。虽然这是一个社区维基,所以你也可以自由编辑它。