Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
strcpy与直接分配:溢出问题_C_String_Strcpy - Fatal编程技术网

strcpy与直接分配:溢出问题

strcpy与直接分配:溢出问题,c,string,strcpy,C,String,Strcpy,这是我学校的练习题,不是家庭作业题: 给出以下声明,编写一段可能 导致strlen(arr)返回不少于8 char arr[4]; 我对这个问题的尝试是:不可能,没有办法做到这一点。由于strlen将返回字符数组中的字符数,直到它遇到第一个\0为止,因此在这种情况下,我看不出有任何方法可以让strlen返回8。我认为如果我们强制为这个数组分配一个8长度的字符串,那么行为是不可预测的 但是,我们的讲师给出的解决方案是: strcpy(arr, Any 8-char-long string);

这是我学校的练习题,不是家庭作业题:

给出以下声明,编写一段可能 导致
strlen(arr)
返回不少于8

char arr[4];
我对这个问题的尝试是:不可能,没有办法做到这一点。由于strlen将返回字符数组中的字符数,直到它遇到第一个\0为止,因此在这种情况下,我看不出有任何方法可以让strlen返回8。我认为如果我们强制为这个数组分配一个8长度的字符串,那么行为是不可预测的

但是,我们的讲师给出的解决方案是:

strcpy(arr, Any 8-char-long string);
例如:

strcpy(arr, "Overflow");
我不明白为什么这是有效的,在我的理解中,我看不出这个数组有足够的空间来容纳这个8长度的字符串,在理解C中的字符串时,我有什么遗漏吗

根据以下声明,编写一段可能导致strlen(arr)返回不少于8的C代码

这是不可能的,因为
arr
只能容纳3个字符和1个空终止符

我对这个问题的尝试是:不可能,没有办法做到这一点

然而,我们的讲师给出的解决方案是:
strcpy(arr,任意8字符长的字符串)

你的指导老师不称职,不应该教C。这将写超出数组的界限,任何事情都可能发生,包括程序崩溃或程序在执行时看起来正常工作

我不明白为什么这是有效的


它不是,它调用未定义的行为。

如果您有strcpy(arr,“Overflow”)
,则会发生缓冲区溢出,并覆盖
arr
数组后的字节。根据被覆盖的内容,
strlen(arr)
可能会返回8,但由于超出数组边界的写入是未定义的行为,因此也可能发生其他情况。还要阅读以下内容:将8个字符长的字符串复制到4个字符的数组中是无效的。但是(我认为)这正是你的导师想要表达的观点。编译器不会阻止你这么做。运行时可能会也可能不会阻止您这样做。因此,您需要非常小心,目标数组足够大,可以容纳复制到其中的任何字符串。顺便说一句,您可以复制到
arr[4]
中的最长字符串是一个3字节的字符串,例如
strcpy(arr,“abc”)
。数组中的第四个字节是
\0
终止符所需的。是的,我也觉得奇怪,因为我认为未定义的行为应该是答案。在所问的问题中,“may”一词是关键。可以,可以将9个或更多字符复制到4字符数组中,
arr
。是的,这样做的行为是未定义的。但它也可能导致后续调用
strlen(arr)
返回8或更多,因为当行为未定义时,这是可能的。它也可能做一些完全不同的事情。有很多未定义行为的生产代码,据任何人所知,它们实际上以一种被视为“有效”的方式运行(不管是什么…)。好吧,为了与之相反,您可以将char arr[4]与一个更大的(比如char bigstring)[999]合并。现在你可以合法地解决这个问题,而不会产生溢出。但这可能比老师想象的要复杂。不管怎么说,假设“你的导师不称职”,根据Lundin的回答,你可以在找到一种更好(更好)的方式来称呼他(或她)不称职的同时指出这个棘手的解决方案:)这显然就是全部要点。他们不是无能的。他们没有说“将导致”,他们说“可能导致”,他们是正确的。所以这是完全可能的,即使它是未定义的行为。你不能说这永远不会发生,因为它是未定义的。@SamiKuhmonen但不管怎样,这都是一个愚蠢的任务。如果我写的是C代码
1/0
那么它也可能导致strlen返回8,因为它也是未定义的行为。教学生期望某个行为是不好的。我不能把给定的作业理解为告诉他们“期望这会返回8”。这与解释正在发生的事情相结合是一件好事。假设它被解释了。它将清楚地表明要点:似乎有效的东西并不总是有效的,所以不要相信“它一开始就有效”等等。我称之为胜任教学。但只有在我们不知道的情况下,它才被正确解释。正如我们所知,这个具体的例子很可能返回8,你的1/0很可能不会返回。@SamiKuhmonen这种推理的问题是,下一步有人会编写代码,比如
do{strcpy(arr,“Overflow”);}while(strlen(arr)然后,不管教什么,他们都会写。很明显,他们没有听和/或理解。这已经被一次又一次地证明了。