【问题标题】:Got stuck with Segmentation Fault Error遇到分段错误错误
【发布时间】:2016-01-21 15:31:52
【问题描述】:

我正在c 中编写一个简单的程序,但我遇到了这个错误

分段错误(核心转储)

我知道Segmentation fault 错误是由于内存访问冲突而发生的。 但我无法弄清楚在下面的简单程序中哪里发生了错误的内存访问。

#include<stdio.h>
int main()
{
    int a = 0;   
    scanf("%d", a);
    printf("%d\n", a);
    return(0);
}

我正在在线编译here,在代码块中它也给出了同样的错误。

【问题讨论】:

  • 问题出在scanf,正如其他人指出的那样,但我也不确定返回。
  • @ClaudioCortese return(0) 有效,但没必要,只需 return 0 即可。
  • @ClaudioCortese 与int i = (5) 有效的方式相同,但你是对的,return 不是函数。我的反对意见是 int main() 签名 -> int main(void)
  • @ClaudioCortese,您可能还忽略了 int main() 并不意味着 main() 采用 0 参数。但相反,这意味着 main() 采用不确定数量的参数。所以int main(void) 真的很重要。因为main() 的唯一有效签名是int main(int argc, char *argv[]);int main(void);
  • @ClaudioCortese 我明确说return (0) 有效,但它不是很好的编码风格。

标签: c segmentation-fault runtime-error


【解决方案1】:

您必须传递一个指向 int 的指针,而不是 int 本身。改成

if (scanf("%d", &a) == 1)
    printf("%d\n", a);
else
    printf("Invalid input\n");

在您的代码中,scanf() 假设int 中的值是它必须写入的地址,从而导致未定义的行为。此外,未定义行为的另一个原因是 a 在调用 scanf() 之前未初始化,但这无关紧要,因为无论如何 未定义行为 都会发生。该标准规定,传递给scanf() 的任何意外类型的参数都会导致未定义的行为

a 在调用 scanf() 之前未初始化的事实意味着,如果您忽略 scanf() 的返回值并且它失败,并且您尝试在代码中的 printf() 中读取 a ,您的代码将调用未定义的行为。这就是检查返回值如此重要的原因。

&amp; address of 运算符生成一个包含其操作数地址的指针,scanf() 需要一个指向参数1 的指针以便能够将结果存储在其中。

请注意,当传递一个数组时,例如,一个char 数组到scanf() 一个带有"%s" 说明符的字符串,你不应该使用&amp; 操作符,因为数组名被转换为一个指向自身的第一个元素,这是 scanf() 在这种情况下需要的。


1注意, 中没有 按引用传递,因此这是您可以更改 @987654343 中的参数的唯一方法@函数。

【讨论】:

  • 糟糕,当你跳转到不同的编程语言时会发生这种情况。从过去几个月开始,我正在使用 Python 进行编码,结果是这样的 :)
  • @Atinesh 不,如果您没有仔细阅读您使用的函数的文档,就会发生这种情况。如果您阅读scanf(),您也会明白为什么我将它的返回值与1 进行比较。并且总是这样做,忽略返回值会导致非常奇怪的错误。
  • P.S.,需要注意的是int实际上是被scanf读取为一个内存地址(好像是一个有效的指针),这样结果就写到了该地址的内存上那 == a 的 VALUE 而不是 a 拥有的内存。
【解决方案2】:

改变

scanf("%d", a);

scanf("%d", &a);

scanf 需要一个指向变量的指针,而不是变量的

我可以建议你在编译时添加-Wall 选项。 在您的情况下,gcc 会警告您:

test.c: In function ‘main’:
test.c:25:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
     scanf("%d", a);
     ^

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    相关资源
    最近更新 更多