提问人:Michael May 提问时间:8/3/2017 更新时间:8/3/2017 访问量:287
是什么导致了短 C 代码中的分段错误?
What makes the segmentation fault in the short C code?
问:
每个人 都。我编写了以下代码,编译并运行了它,但我遇到了分段错误。
#include <stdio.h>
typedef long long ll_t;
void store_prod(ll_t * dest, int x, ll_t y) {
* dest = x * y;
}
int main(void)
{
int a = 2049;
ll_t b = 2147483645;
ll_t * c;
store_prod(c, a, b);
printf("%d * %lld = %lld\n", a, b, *c);
return 0;
}
Dev-C++ 中的调试器转储以下内容:
0x00401500 <+0>: push %ebp
0x00401501 <+1>: mov %esp, %ebp
0x00401503 <+3>: push %ebx
0x00401504 <+4>: sub $0xc, %esp
0x00401507 <+7>: mov 0x10(%ebp), %eax
0x0040150a <+10>: mov %eax, -0x10(%ebp)
0x0040150d <+13>: mov 0x14(%ebp), %eax
0x00401510 <+16>: mov %eax, -0xc(%ebp)
0x00401513 <+19>: mov 0xc(%ebp), %eax
0x00401516 <+22>: mov %eax, %edx
0x00401518 <+24>: sar $0x1f, %edx
0x0040151b <+27>: mov -0x10(%ebp), %ecx
0x0040151e <+30>: mov %ecx, %ebx
0x00401520 <+32>: imul %edx, %ebx
0x00401523 <+35>: mov -0xc(%ebp), %ecx
0x00401526 <+38>: imul %eax, %ecx
0x00401529 <+41>: add %ebx, %ecx
0x0040152b <+43>: mull -0x10(%ebp)
0x0040152e <+46>: add %edx, %ecx
0x00401530 <+48>: mov %ecx, %edx
0x00401532 <+50>: mov 0x8(%ebp), %ecx
0x00401535 <+53>: mov %eax, (%ecx) ; The problem lies with this line
0x00401537 <+55>: mov %edx, 0x4(%ecx)
0x0040153a <+58>: add $0xc, %esp
0x0040153d <+61>: pop %ebx
0x0040153e <+62>: pop %ebp
0x0040153f <+63>: ret
注册信息:
EAX 0x7fffe7fd 2147477501
ECX 0x40234e 4203342
EDX 0x400 1024
EBX 0x0 0
ESP 0x63fe58 0x63fe58
EBP 0x63fe68 0x63fe68
ESI 0x3d 61
EDI 0xb70d48 11996488
EIP 0x401535 0x401535 <store_prod+53>
EFLAGS 0x10206 [ PF IF RF ]
CS 0x23 35
SS 0x2b 43
DS 0x2b 43
ES 0x2b 43
FS 0x53 83
GS 0x2b 43
地址 [%ecx](即 0x40234e)似乎覆盖了代码,但为什么要出现这样的访问冲突?C代码有什么问题吗? 非常感谢您的帮助!
答:
7赞
CIsForCookies
8/3/2017
#1
您尝试写入不属于您的内存→未定义的行为(段错误可选)
在行中声明,但您使用 no 或将其指向有效地址(例如:ll_t * c;
c
malloc
ll_t d; ll_t *c = &d;
)
更改为 并检查是否失败,或更改为ll_t * c;
ll_t * c = malloc(sizeof(ll_t));
malloc
ll_t d; ll_t *c = &d;
编辑:正如 @Ajay Brahmakshatriya 所指出的,还有另一种(按时间顺序排列)未定义的行为 - 将未初始化的变量 () 发送到 。c
store_prod(...)
评论
0赞
CIsForCookies
8/3/2017
@fuz你是怎么射出那支箭的?(努力提高我的写作:))
1赞
fuz
8/3/2017
在具有德语布局的 Linux 上,它是 AltGr + I。或者对于 html 实体,它会产生 →(显然在这里不起作用)。→
0赞
Ajay Brahmakshatriya
8/3/2017
在“写入你不拥有的内存”之前,有一个关于Unintialised值的读数。
0赞
CIsForCookies
8/3/2017
@AjayBrahmakshatriya那不是只是读取一个中间值而不使用它,我认为这不应该被认为是ub吗?
3赞
chqrlie
8/3/2017
#2
崩溃的原因是将值存储到未初始化指针指向的位置时未定义的行为。c
无需创建指针,将其定义为 并将其地址传递给函数:c
ll_t
#include <stdio.h>
typedef long long ll_t;
void store_prod(ll_t *dest, int x, ll_t y) {
*dest = x * y;
}
int main(void) {
int a = 2049;
ll_t b = 2147483645;
ll_t c;
store_prod(&c, a, b);
printf("%d * %lld = %lld\n", a, b, c);
return 0;
}
您可以只返回计算值,但我想此代码示例的目的是教授使用指针返回计算值。
评论
ll_t * c;
-->ll_t d, *c = &d;
store_prod(c, a, b);
c