简体   繁体   English

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

[英]Segmentation fault on program with scanf

This is a small piece of code that I made while trying to understand how malloc and pointers work. 这是我在尝试理解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++;
    }
}

For some reason that I can't understand, I keep getting a segmentation fault. 由于某些我无法理解的原因,我不断遇到分段错误。 This error repeatedly happens on the last scanf() and I do not know why. 这个错误在最后一次scanf()上重复发生,我不知道为什么。 I know i have to pass pointer to scan f and num is already a pointer so i thought that i would not need to include the &. 我知道我必须将指针传递给扫描f并且num已经是指针所以我认为我不需要包含&。 But, I received a segmentation fault earlier if i do not. 但是,如果我不这样做,我会更早收到分段错误。 Also, I believe I have allocated the correct amount of space using malloc but I am not sure. 另外,我相信我已经使用malloc分配了正确的空间,但我不确定。 Any help with what is happening here would be appreciated. 任何有关这里发生的事情的帮助将不胜感激。

You returned the pointer to the local variable buffer , which will banish on exiting the function buffer . 您返回了指向本地变量buffer的指针,这将取消退出函数buffer

You should remove the & used in the return statement and return the pointer to allocated buffer. 您应该删除return语句中的& ,并将指针返回到已分配的缓冲区。

Also checking whether malloc() is successful should be added. 还应该添加检查malloc()是否成功。

There are a couple of issues that I can see, and one of them is definitely a problem. 我可以看到一些问题,其中一个肯定是个问题。 In function, int *buffer (int count) 在函数中, int *buffer (int count)

return &buffer;

This will return address of buffer which is already a local int * variable. 这将返回已经是本地 int *变量的buffer地址。 So when the return happens, variable buffer would no longer be valid. 因此,当返回发生时,变量buffer将不再有效。 Hence, the address is invalid. 因此,地址无效。

One of the ways to go ahead as of now would be avoiding a function call buffer and using calloc() . 到目前为止,其中一种方法是避免使用函数调用buffer并使用calloc() Because, subject to availability, calloc() will allocate the memory of requested length, which will be initialized to 0 by default. 因为,根据可用性, calloc()将分配所请求长度的内存,默认情况下将初始化为0。 Or, the other way would be making the buffer pointer a global variable. 或者,另一种方法是使buffer指针成为全局变量。

Also, with existing implementation, there needs a piece of code which checks if malloc returned anything or not. 此外,对于现有的实现,需要一段代码来检查malloc返回任何内容。 That would indicate if the memory was allocated or not. 这表明内存是否已分配。 Something like this would do: 这样的事情会做:

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

Additionally, I see the for loop which looks a bit weird than what it should look like: 另外,我看到for循环看起来有点像它看起来有点奇怪:

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

I take that you are trying to loop the count times and fill a 0 in buffer. 我认为你试图循环count次数并在缓冲区中填充0。 This could have been achieved by 这可以通过以下方式实现

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

So, a malloc() is followed by en error-check and then followed by a for to fill the allocated memory with zeroes. 因此, malloc()之后是错误检查,然后是for ,用零填充分配的内存。 So, using calloc makes life a lot easier. 因此,使用calloc可以让生活变得更轻松。

Importantly, you allocate memory but you don't seem to have a code that de-allocates (frees) it. 重要的是,您分配内存,但似乎没有一个代码可以解除分配(释放)它。 There are ample of examples to refer for doing that. 有很多例子可以参考。 I would recommend you to read concepts like Memory Leakage, Dangling Pointers and using valgrind or similar thing to validate the memory usage. 我建议你阅读Memory Leakage,Dangling Pointers等概念,并使用valgrind或类似的东西来验证内存使用情况。

As a side-note and not a rule of thumb, always make sure that the names you use for variables are different than the names you use with functions. 作为附注而非经验法则,请始终确保用于变量的名称与用于函数的名称不同。 That creates a hell a lot of confusion. 这造成了很多混乱。 Going ahead with existing naming habit, you'll have a tough day when the code is reviewed. 继续使用现有的命名习惯,您将在审核代码时度过艰难的一天。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM