我看到有人这样做,数组索引从1开始,而不是从C开始。
a = (int *) malloc(sizeof(int)*3) - 1
这有什么风险吗?
答案 0 :(得分:10)
理论风险:只有空指针和指向对象的指针才有效。其他指针在使用时触发未定义的行为(如果它们正在悬空)或通过指针算法创建它们。
实际风险:由随机代码审核人员投降。
答案 1 :(得分:3)
有风险吗?肯定。
malloc
来电将从地址 A 开始为您预留一些空间,但之后您将a
设置为 A-4 。由于 A-4 可能会存储一些重要内容,如果您忘记从1开始编制索引并无意中覆盖a[0]
处的值,则可能会遇到错误的时间。
但更重要的是,为什么?它只会让读取代码的人感到困惑。
我会建议反对这种亵渎;)
答案 2 :(得分:0)
三件事:
首先 - 对我来说,使用指向不属于您的程序的地址的指针是不好的做法。一旦你忘记你创建了一个以1开头的数组,你就可以在调试代码时玩得开心(相信我,你会忘记)。
第二 - 所以你写了类似的东西。几个月之后,其他人也开始对你的代码做些什么,并没有注意到你把它放在那里。他将很乐意调试此代码。简而言之,这违反了总合同。每个人都希望数组或几乎任何带[]的东西从0开始并以“length - 1”结束。
第三 - 因为你违反了一般合同,你所做的数组不适用于任何希望你的数组以0开头的标准库。每当你决定使用你的数组的任何库时,你将不得不记住增加你将作为参数传递的指针。
有了这个,您将需要做很多记忆,思考和评论(对于使用您的代码的任何人)。思考和记忆应该留给创造力而不是锅炉板代码。
答案 3 :(得分:0)
只有两种情况,标准允许指针值指向除有效对象之外的其他内容:
null
指针值并不指向任何内容。可以复制空指针,并且可以使用==
或!=
运算符进行比较。在空指针上使用加法,减法或关系运算符;使用解除引用操作符将产生未定义的行为,除非在某些情况下它既不请求实际的解引用操作符也不请求指针算法[例如即使sizeof *p
为空,p
也是合法的。
对于任何对象,都可以有一个指向该对象的指针,或一个指针"一个过去"那个对象;向前者添加一个将产生后者,从后者中减去一个将产生前者。在"过去"上使用==
或!=
运算符指针和指向不同对象的指针有时可能会将它们报告为相等,即使在使用指向另一个对象的指针进行的访问是合法的并且使用" one-past"指针会触发未定义的行为。
您的代码尝试生成一个指针,该指针不指向任何有效对象,并且不适合任何描述的行为类别。请注意,创建指向"数组的指针是可能且合法的。 N个元素的有效下标范围从KN到K-1,对于从0到N的任何K(包括N个对象的数组,它可以生成指向任何N个对象的指针,或者一个指针"一个过去"最后一个,总共N + 1个有效指针值)。但是,在第一个对象之前的指针无效。