使用scanf对程序进行分段错误

问题描述 投票:3回答:2

这是我在尝试理解malloc和指针如何工作时所做的一小段代码。

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

int *buffer (int count)
{
  int *buffer = malloc (count * sizeof(int));

  for (int i = 0; 0 <= i && i < count; i++)
    {
      buffer[i] = 0;
    }

  return &buffer;
}

int main ()
{
  int size = 0;
  int i = 0;
  scanf ("%d", &size);

  int *num = buffer (size);
  while (i < size)
    {
      scanf ("%d", &num[i]);
      i++;
    }
}

由于某些我无法理解的原因,我不断遇到分段错误。这个错误在最后一次scanf()上重复发生,我不知道为什么。我知道我必须将指针传递给扫描f并且num已经是指针所以我认为我不需要包含&。但是,如果我不这样做,我会更早收到分段错误。另外,我相信我已经使用malloc分配了正确的空间,但我不确定。任何有关这里发生的事情的帮助将不胜感激。

c
2个回答
2
投票

我可以看到一些问题,其中一个肯定是个问题。在功能,int *buffer (int count)

return &buffer;

这将返回buffer的地址,该地址已经是本地int *变量。因此,当返回发生时,变量buffer将不再有效。因此,地址无效。

到目前为止,其中一种方法是避免函数调用buffer并使用calloc()。因为,根据可用性,calloc()将分配所请求长度的内存,默认情况下将初始化为0。或者,另一种方式是使buffer指针成为全局变量。

此外,对于现有的实现,需要一段代码来检查malloc是否返回任何内容。这表明内存是否已分配。这样的事情会做:

int *buffer = malloc (count * sizeof(int));
if(buffer == NULL)
{
    // Some error handling
    return 0;
}

另外,我看到for循环看起来有点像它应该看起来有点奇怪:

for (int i = 0; 0 <= i && i < count; i++)

我认为你试图循环count次并在缓冲区填充0。这可以通过以下方式实现

for (int i = 0; i < count; i++)

因此,malloc()之后是错误检查,然后是for,用零填充分配的内存。因此,使用calloc可以让生活变得更轻松。

重要的是,您分配内存,但似乎没有一个代码可以解除分配(释放)它。有很多例子可以参考。我建议你阅读Memory Leakage,Dangling Pointers等概念,并使用valgrind或类似的东西来验证内存使用情况。

作为附注而非经验法则,请始终确保用于变量的名称与用于函数的名称不同。这造成了很多混乱。继续使用现有的命名习惯,您将在审核代码时度过艰难的一天。


3
投票

你返回了指向局部变量buffer的指针,这将消除退出函数buffer

您应该删除&语句中使用的return并将指针返回到已分配的缓冲区。

还应该补充检查malloc()是否成功。

© www.soinside.com 2019 - 2024. All rights reserved.