是否使用while(*p++)检查数组是否有更多的危险元素?
如果在下一个内存位置上有一些值,并且这个值不是数组的一部分,那么可能会出现问题。
这个简单的代码:
#include <stdio.h>
void f(float *p) {
printf("%p : %.f\n", p, *p);
while(*p++){
printf("%p : %.f\n", p, *p);
}
printf("%p : %.f\n", p, *p);
}
int main() {
float p[] = {2.2, 3.2};
f(p);
return 0;
}给出这个输出:
0x7fffed4e8f10 : 2
0x7fffed4e8f14 : 3
0x7fffed4e8f18 : 0
0x7fffed4e8f1c : 0因此,如果在0x7fffed4e8f18上值为≠0,它会使我的代码出错吗?
发布于 2014-10-03 15:55:20
已经有很多答案能够很好地解释通过数组边界而产生的未定义行为。但还有另一个(潜在的)问题,还没有人提过。
如果数组可以包含0作为有效值,那么您将假定错误的大小。那是,
void
f(float * p)
{
do
{
printf("% .01f\n", *p);
}
while(*p++);
}
int
main()
{
float p[] = {-1.0f, -0.5f, 0.0f, 0.5f, 1.0f};
f(p);
return 0;
}威尔输出
-1.00
-0.50
0.00“忽略”剩下的元素。虽然这个特定的示例不会调用未定义的行为,但它可能不是您所期望的。
我想您已经用字符串编程来改变这种模式了。按照约定,我们需要一个字符数组来表示文本字符串。
如果这两项要求都得到满足,请执行
void
roll_all_over_it(char * string)
{
while(*string);
{
putchar(*string++);
}
}按合同是安全的。
这使得使用字符串更加方便,因为我们不需要在每个字符串旁边维护一个整数来跟踪它的长度。另一方面,它使相当多的(不小心编写的)程序容易受到缓冲区溢出攻击,而且这个假设还会产生其他问题。例如,请参见fgets在GNU libc手册中的讨论
警告:如果输入数据有空字符,则无法判断。因此,除非您知道数据不能包含null,否则不要使用
fgets。不要使用它读取用户编辑的文件,因为如果用户插入空字符,则应该正确处理该字符或打印清楚的错误消息。我们建议使用getline而不是fgets。
发布于 2014-10-03 15:21:40
一旦p超出了数组的界限,取消引用它就会调用未定义的行为。所以是的,这样做是危险的。
发布于 2014-10-03 15:26:15
是的,它是:您的函数接受一个指针参数,但是您没有检查以确保它不是空指针。不允许删除空指针。
正如其他人所指出的:取消引用无效指针(超出界限)会导致未定义的bahviour,这是不好的。
此外,您正在使用正确的格式字符串打印指针(%p),但使用-Wall -pedantic编译代码。打印指针值是必须转换到void *的指针的少数几种情况之一。换法:
printf("%p : %.f\n", p, *p);至
printf("%p : %.f\n", (void *) p, *p);最新情况:
作为对您的评论的回应:您似乎实际上试图确定作为参数传递的数组的长度。简单的事实是,你不能。一个数组衰变成一个指针。指针不是数组,因此无法确定原始数组的长度。至少:不可靠。
如果您正在处理一个数组,并且您想知道它的长度:让函数的调用方传递长度作为参数:
void f(float *arr, size_t arr_len)
{
if (arr == NULL)
exit( EXIT_FAILURE );//handle error
//do stuff
}简而言之,函数在很大程度上依赖于数组后面有一个0。函数本身也可以通过NULL调用,取消引用null也是非法的。所以是的,你的密码很危险。
//example setup
float foo = 123.4f
float *bar = malloc(123 * sizeof *foo);//<-- uninitialized memory, contains junk
//omitting if (bar == NULL) check, so bar might be null
//dangerous calls:
f(&foo);
f(bar);//<-- bar could be null if malloc failed, and contains junk if it didn't dangerous
f(NULL);https://stackoverflow.com/questions/26181822
复制相似问题