在strcpy的分段故障 [英] Segmentation fault in strcpy

查看:146
本文介绍了在strcpy的分段故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

审议以下

    char str[5];
    strcpy(str,"Hello12345678");
    printf("%s",str);

在运行此程序会产生分段错误。

When run this program gives segmentation fault.

但是,当strcpy的被替换之后,程序运行正常。

But when strcpy is replaced with following, program runs fine.

strcpy(str,"Hello1234567");

所以,问题是应该试图复制为str超过500个字符长度的任何其他字符串时崩溃。

So question is it should crash when trying to copy to str any other string of more than 5 chars length.

那么,为什么它没有崩溃的Hello1234567,只有长度为13或大于13的崩溃Hello12345678,即字符串。

So why it is not crashing for "Hello1234567" and only crashing for "Hello12345678" ie of string with length 13 or more than 13.

该计划是32位计算机上运行。

This program was run on 32 bit machine .

推荐答案

有三种标准的行为,你应该会感兴趣。

There are three types of standards behaviour you should be interested in.

1 /的定义的行为的。这将在所有符合实施工作。随意使用这一点。

1/ Defined behaviour. This will work on all complying implementations. Use this freely.

2 /的实现定义的行为的。如前所述,这取决于实现,但至少它仍然定义。实现需要记录他们在这种情况下做什么。使用这个,如果你不关心可移植性。

2/ Implementation-defined behaviour. As stated, it depends on the implementation but at least it's still defined. Implementations are required to document what they do in these cases. Use this if you don't care about portability.

3 / 未定义行为的。任何事情都有可能发生。我们的意思的任何的,甚至包括整个计算机折叠成一个裸奇点和吞咽自己,你和你的同事的相当大的比例。从来不使用这个。永远!认真!不要让我到那儿。

3/ Undefined behaviour. Anything can happen. And we mean anything, up to and including your entire computer collapsing into a naked singularity and swallowing itself, you and a large proportion of your workmates. Never use this. Ever! Seriously! Don't make me come over there.

复制多于4个字符和一个零字节到的char [5] 是未定义的行为。

Copying more that 4 characters and a zero-byte to a char[5] is undefined behaviour.

严重的是,它并不重要,为什么你的程序有14个字符的崩溃而不是13,你几乎可以肯定覆盖在堆栈上一些非崩溃的信息和你的程序将最有可能产生反正不正确的结果。事实上,暴跌是更好,因为至少它阻止你依靠可能的不良影响。

Seriously, it doesn't matter why your program crashes with 14 characters but not 13, you're almost certainly overwriting some non-crashing information on the stack and your program will most likely produce incorrect results anyway. In fact, the crash is better since at least it stops you relying on the possibly bad effects.

增加数组的大小为更合适的(的char [14] 在这种情况下,与现有的资料),或者使用一些其他的数据结构,可以应付。

Increase the size of the array to something more suitable (char[14] in this case with the available information) or use some other data structure that can cope.

更新:

既然你似乎很关心找出为什么一个额外的7个字符不会出现问题,但8个字呢,让我们设想在进入可能的堆栈布局的main() 。我说可能,因为实际的布局取决于你的编译器使用调用约定。由于C启动code调用的main() ARGC 的argv ,堆栈在开始的main(),如果字符分配空间后,[5] ,可能是这样的:

Since you seem so concerned with finding out why an extra 7 characters doesn't cause problems but 8 characters does, let's envisage the possible stack layout on entering main(). I say "possible" since the actual layout depends on the calling convention that your compiler uses. Since the C start-up code calls main() with argc and argv, the stack at the start of main(), after allocating space for a char[5], could look like this:

+------------------------------------+
| C start-up code return address (4) |
| argc (4)                           |
| argv (4)                           |
| x = char[5] (5)                    |
+------------------------------------+

当你写字节 Hello1234567 \\ 0

strcpy (x, "Hello1234567");

X ,它会覆盖 ARGC 的argv 不过,从的main(),没关系。具体来说您好填充 X 1234 填充的argv 567 \\ 0 填充 ARGC 。只要不实际尝试的使用 ARGC 和/或的argv 之后,你会好起来的:

to x, it overwrites the argc and argv but, on return from main(), that's okay. Specifically Hello populates x, 1234 populates argv and 567\0 populates argc. Provided you don't actually try to use argc and/or argv after that, you'll be okay:

+------------------------------------+ Overwrites with:
| C start-up code return address (4) |
| argc (4)                           |   '567<NUL>'
| argv (4)                           |   '1234'
| x = char[5] (5)                    |   'Hello'
+------------------------------------+

不过,如果你写 Hello12345678 \\ 0 (注意额外的8),以 X ,它将覆盖在 ARGC 的argv 的返回地址的一个字节,因此当的main()试图返回到C启动code,它熄灭成童话的土地,而不是:

However, if you write Hello12345678\0 (note the extra "8") to x, it overwrites the argc and argv and also one byte of the return address so that, when main() attempts to return to the C start-up code, it goes off into fairy land instead:

+------------------------------------+ Overwrites with:
| C start-up code return address (4) |   '<NUL>'
| argc (4)                           |   '5678'
| argv (4)                           |   '1234'
| x = char[5] (5)                    |   'Hello'
+------------------------------------+

同样,这完全取决于你的编译器的调用约定。这是可能的不同的编译器会直到你又写了三个大字总是垫出阵列的4字节的倍数和code不会失败在那里。即使是相同的编译器可能会在堆栈帧上分配不同的变量,以确保对齐是满意的。

Again, this depends entirely on the calling convention of your compiler. It's possible a different compiler would always pad out arrays to a multiple of 4 bytes and the code wouldn't fail there until you wrote another three characters. Even the same compiler may allocate variables on the stack frame differently to ensure alignment is satisfied.

这就是他们的意思是不确定的:你没有的知道的有什么事情发生。

That's what they mean by undefined: you don't know what's going to happen.

这篇关于在strcpy的分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆