我接受了一次采访,我被问到这个问题:
您如何看待以下内容?
int i; scanf ("%d", i); printf ("i: %d\n", i);
我回答:
我做出的回应是错误的。我不知所措。
之后他们开除了我:
在某些情况下程序会崩溃并导致核心转储。
我无法理解为什么程序会崩溃?谁有人解释我的原因?任何帮助表示赞赏。
答案 0 :(得分:45)
定义变量时,编译器为该变量分配内存。
* {
margin: 0;
padding: 0;
border: 0;
text-decoration: none;
vertical-align: baseline;
border: none;
font-weight: normal;
}
html, html a {
font-size: 10px;
-webkit-text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
text-shadow: 1px 1px 1px rgba(0,0,0,0.004);
}
html {
}
body {
}
a {color: inherit;}
a:visited {text-decoration: none; color: inherit;}
#namelogo p {
padding-left: 1rem;
padding-top: 1rem;
font-size: 3rem;
color: white;
text-align: left;
}
#namelogo a {
font-size: 3rem;
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
-ms-transition: all 0.2s ease;
-o-transition: all 0.2s ease;
}
#namelogo a:hover {
text-shadow: 1px 1px 20px #fff;
}
#headline {
position:relative;
min-height: 100vh;
max-width: 100vw;
background-color: black;
background-position: center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#layer {
min-height: inherit;
width: inherit;
}
#vertical-align {
position: absolute;
top: 52%;
-moz-transform: translateY(-52%);
-ms-transform: translateY(-52%);
-webkit-transform: translateY(-52%);
transform: translateY(-52%);
width: 100%;
}
.posttitle {
padding-left: 1.5rem;
padding-right: 1.5rem;
text-align: center;
color: white;
font-size: 4rem;
line-height: 90%;
font-family: "Crimson Text", "Georgia", serif;
}
.postinfo {
padding-top: 1.3rem;
padding-left: 2rem;
padding-right: 2rem;
text-align: center;
font-family: "Crimson Text", "Georgia", serif;
color: white;
font-size: 1.3rem;
}
#content {
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
#content h1 {
font-family: "Crimson Text", "Georgia", serif;
color: #353535;
font-size: 2.8rem;
line-height: 3.4rem;
padding-top: 8rem;
padding-bottom: 4.5rem;
padding-left: 2rem;
padding-right: 2rem;
}
#content h2 {
font-family: "Crimson Text", "Georgia", serif;
color: #333333;
font-size: 2.5rem;
padding-top: 2rem;
padding-bottom: 2rem;
padding-left: 2rem;
padding-right: 2rem;
}
#content p {
font-family: "Crimson Text", "Georgia", serif;
color: #353535;
padding-left: 2rem;
padding-right: 2rem;
font-size: 2.3rem;
word-wrap: break-word;
}
上面定义的 <html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href='https://fonts.googleapis.com/css? family=Crimson+Text:400,400italic,600,600italic,700,700italic' rel='stylesheet' type='text/css'>
</head>
<body>
<div id="headline" style="background-image: url(https://images.unsplash.com/photo-1449710146567-1e282fa41f2f?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&s=c1bffcef22907f217af2fdbc3e430855);">
<div id="layer" style="background-color: rgba(0,0,0,0.4)">
<div id="namelogo">
<p><a href="../index.html">Peter Dam</a></p>
</div>
<div id="vertical-align">
<h1 class="posttitle">Why the Unfamiliar is Frightening and Why You Should Face It Anyway</h1>
<p class="postinfo">January 4, 2016 • 13 minute read • by Peter Dam</p>
</div>
</div>
</div>
<div id="content">
<h1>I have never done this before. My decision to pursue a future as a writer came as a surprise to myself. When I tell people about it—especially that it will revolve around a blog—I typically receive a sympathetic, concerned smile. A smile that tells me they think it's an appealing ambition, but also naïve.</h1>
<p>
I often find myself procrastinating and postponing the act of sitting down to write. My mind is mostly on how much better the other writers are, and I feel hesitant to begin. Instead, I convince myself that it's more logical to finish designing my website first, or to read an article about how to write well.
<br><br> </p>
</div>
<div id="footer">
<p> © 2016 Peter Dam. All rights reserved.</p>
</div>
</body>
</html>
未初始化且具有不确定的值。
要将数据写入为int i; // The compiler will allocate sizeof(int) bytes for i
分配的内存位置,您需要指定变量的地址。声明
i
将用户将i
数据写入分配给scanf("%d", &i);
的内存位置。
如果未在int
之前放置i
,则&
会尝试将输入数据写入内存位置i
,而不是scanf
。由于i
包含不确定的值,因此它可能包含一个等于内存地址值的值,或者它可能包含一个超出内存地址范围的值。
在任何一种情况下,程序可能会表现不正常并导致未定义的行为。在那种情况下,任何事情都可能发生。
答案 1 :(得分:18)
因为它调用未定义的行为。 scanf()
系列函数在找到"%d"
说明符时期望指向整数的指针。您传递的是一个整数,可以将其解释为某个整数的地址但不是。这在标准中没有定义的行为。它确实会编译(会发出一些警告但)但它肯定会以一种意想不到的方式工作。
在代码中,还有另一个问题。 i
变量永远不会被初始化,因此它将具有不确定的值,这是未定义行为的另一个原因。
请注意,标准并未说明当您在某种其他类型的情况下传递给定类型时会发生什么,无论您交换什么类型,它都是简单的未定义行为。但是这种特殊情况属于特殊考虑因素,因为指针可以转换为整数,但只有在转换回指针并且整数类型能够正确存储值时才会定义行为。这就是它编译的原因,但肯定无法正常工作。
答案 2 :(得分:10)
您传递的数据类型错误(预计会int*
,但会传递int
)到scanf()
。这将导致未定义的行为。
任何未定义的行为都可能发生。该程序可能会崩溃,可能不会崩溃。
在一个典型的环境中,我猜程序会在一些&#34;地址&#34;它指向一个不被操作系统写入的位置传递给scanf()
,写入那里将使操作系统终止应用程序,并将其视为崩溃。
答案 3 :(得分:10)
其他答案尚未提及的一件事是在某些平台上sizeof (int) != sizeof (int*)
。如果参数以某种方式传递*,scanf
可能会吞噬另一个变量或返回地址的一部分。更改返回地址很可能会导致安全漏洞。
*我不是汇编语言专家,所以请耐心等待。
答案 4 :(得分:5)
我无法理解为什么程序会崩溃?任何人都可以解释我的原因。任何帮助表示赞赏。
也许更多应用:
int i = 123;
scanf ("%d", &i);
使用第一个命令为一个整数值分配内存并在此内存块中写入123。对于此示例,我们假设此内存块的地址为0x0000ffff
。使用第二个命令读取输入,scanf将输入写入内存块0x0000ffff
- 因为您没有访问(取消引用)此变量i
的值,而是它的地址。
如果您使用命令scanf ("%d", i);
而是将输入写入内存地址 123
(因为这是存储在此变量中的值)。显然,这可能会出现严重错误并导致崩溃。
答案 5 :(得分:0)
由于 scanf 中没有 &(&(&))(按照标准的要求),所以只要我们输入这个值,程序就会突然终止,无论程序中再写多少行代码。< /p>
-->> 我执行并发现在代码块中。
如果我们在 turbo c 编译器中运行相同的程序,那么它会完美地运行所有行,即使是在 scanf 之后,但唯一的事情,因为我们知道 i 打印的值将是垃圾。
结论:- 因为在某些编译器上它会运行而在某些编译器上不会运行,所以这不是一个有效的程序。