我正在将一个极大而且很旧(25年!)的程序从C转换为C ++。
在其中有许多(非常非常多)我使用各种整数索引访问全局一维UBYTE数组的地方。有时这个指数可能是负面的。
我有时候,但并非总是如此,陷入困境,并确保没有出错,但作为一个腰带和大括号的测量,我实际上遇到了麻烦,确保在阵列前面有另一块内存并填充它使用正确的值,如果我意外省略了陷阱负数条件,那么仍然会在数组访问中获取正确的答案。这实际上很多年都很好。
但现在在C ++下,似乎访问具有负数的数组的行为有所不同,现在我的程序表现不佳。我修正了一个未处理的负数的案例,该程序看起来工作正常,但我很紧张,我没有陷入所有的负数,可能会有问题。
所以现在我的问题是,在运行时,有没有办法检测任何访问负索引数组的实例?如果有人能想出答案,我会留下深刻的印象。如果您非常肯定无法以任何自动方式完成,那么告诉我这也是有价值的信息。
我应该补充一点,我还不是一个真正的C ++程序员。到目前为止,我所做的只是绝对最低限度(几乎没有)让程序在C ++编译器下编译。因此,如果您的答案涉及花哨的“专家,C ++解决方案”,那么请尝试用一个音节的单词解释或给我一个链接,以便我可以查找。
答案 0 :(得分:26)
你能用一个带有重载operator []的对象替换全局一维ubyte数组吗?使用int输入的绝对值可能会解决您的一些问题。
编辑:根据数组的使用模式(没有指针shenanigans),使用具有重载operator []的对象实际上对数组的用户完全透明,因此我的建议。
答案 1 :(得分:6)
你知道指数的界限吗?
根据Siyfion的回答阅读评论,似乎在您的问题域中允许使用否定指数,因此试图强制所有指数为正数是没有意义的。一个更好的解决方案是允许负指数而不破坏任何语言规则(你的C版本也做了btw。你很幸运它没有爆炸;)
因此,如果您知道要使用的索引在-x到y的范围内,只需创建一个大小为x + y的数组,并在访问该数组时使用指向第x个元素的指针。
例如,假设您需要一个索引为-4到5的数组:
int arr[10];
int* ptr = arr+4;
// use ptr when you need to index into the array:
ptr[-4]; // is valid, reads arr[0]
ptr[5]; // is valid, reads arr[9]
当然可以(也应该)在C中完成。
另一条建议是不直接访问原始数组。改为定义简单的访问器功能。 (例如,但不一定,通过将数组放在一个类中。如果你把它放在一个类中,你可以重载operator []所以它甚至看起来像就像一个数组仍然)< / p>
这的开销恰好为零(不是“接近零,或者接近于零,你不会注意到差异”,但是零。生成的代码将完全相同如果您直接访问了数组),因为编译器将内联短函数,但它还允许您插入额外的检查,以便您可以在调试版本中验证您是否永远不会超过数组的范围。
答案 2 :(得分:4)
某种内存使用检查程序可能有效,特别是如果您可以将阵列强制到其自己的页面。我在Linux上使用valgrind
,不知道你在Windows上使用了什么 - purify
?
答案 3 :(得分:3)
包裹它。或者,检查您的编译器是否支持边界检查。 最糟糕的情况是,我不会在数组中将有效值放在负数。我会把公然 错误的值,以便在发生这种情况时得到一个明显错误的值。如果没有调试器,你就不会明确指出这个问题,但至少你有一个明确的警告,某些代码正在这样做。
答案 4 :(得分:3)
在运行时,对我来说有没有办法 检测任何访问实例 负索引的数组?
用std::vector替换全局数组。替换
使用array[index]
语法
vector.at(index)
这正是你所要求的:它增加了运行时数组绑定检查。
答案 5 :(得分:2)
我能想到的唯一方法是将数组包装在一个检查索引为正的方法中。
答案 6 :(得分:1)
就个人而言,我会尝试弄清楚为什么你的任何指数都可能是负面的;很明显,他们会返回一个不正确的值,所以你肯定不应该让索引变为负数?
修复允许它们变为负片的代码,而不是试图将方形插头装入圆孔(可以这么说);)
答案 7 :(得分:0)
您可以做的一件事是,您可以检查索引的最小值,然后从该索引开始填充数组。
a [-i] = *(a - i)
所以从(a-i)开始作为你的基地址而不是(a)所以你只需要移动数组并获得所需的值。
答案 8 :(得分:0)
通过MSDN查看此示例: