[英]Why isn't this code printing my array?
我在这里有一个 integer 数组排序程序,但我有一个问题:每当我运行程序时,我有时会收到“变量‘数字’周围的堆栈已损坏”消息,有时它只是重复打印出数字 8。这是我的代码(在 Visual C++ 2010 中编译):
#include <iostream>
#include <cstdlib>
using std::cout;
using std::endl;
void swap(int *x, int *y)
{
int tmp=0;
tmp = *x;
*x = *y;
*y = tmp;
tmp = 0;
}
int main()
{
int numbers[13] = {8,16,23,487,2,301,48,0,13,10,644,12};
int size = sizeof(numbers) / sizeof(int);
//sort
int i = 0;
int* a = &numbers[0];
int* b = &numbers[1];
while(i < size){
if(*a > *b){
swap(a, b);
}
*a++;
*b++;
i++;
}
//Print our results
int loopIterator = 0;
int numToPrint = 0;
while(loopIterator < size){
cout << numbers[numToPrint] << endl;
loopIterator++;
}
system("PAUSE");
}
首先,您永远不会增加numToPrint
,因此您永远不会打印超过numbers[0]
的值。 至少将您的代码更改为:
while(loopIterator < size){
cout << numbers[numToPrint++] << endl;
loopIterator++;
}
其次,由于您的while
循环使用测试i < size
,因此在循环的最后一次迭代中,您将在b
指针的numbers
之外访问 memory ,并可能将该值交换到numbers
的最后一个槽中(即,其中a
指向)。 您想将测试更改为i < (size - 1)
以避免这种情况。 例如,如果在i == 0
您有a = &numbers[0]
和b = &numbers[1]
,那么到i == 12
时,您将得到a = &numbers[12]
和b = &numbers[13]
... b
在此实例中指向的值超出了数组的末尾。 根据您的编译器如何设置堆栈以及您在堆栈上分配numbers
的方式,如果您最终b
指向您的main()
的激活记录数据结构,这实际上可能会对您的程序造成一些破坏function,并反过来破坏它。
我假设您正在将数组排序作为练习来实现。 这并不能真正回答您的问题,但我想我会发布以供参考,无论如何。 这是使用 STL 实现所需结果的一种方法:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int numbers[] = { 8, 16, 23, 487, 2, 301, 48, 0, 13, 10, 644, 12 };
size_t const size = sizeof(numbers) / sizeof(numbers[0]);
int * const begin = numbers;
int * const end = numbers + size;
std::sort(begin, end);
std::copy(begin, end, std::ostream_iterator<int>(std::cout, "\n"));
}
好吧,我立即跳出来的一件事是,您永远不会增加 numToPrint,因此它将打印出 numbers[0],size 次数。
我会将您的打印部分改写为
for (int i = 0; i < size; i++)
cout << numbers[i] << endl;
这样您就可以摆脱代码的打印结果部分,因为上面是做同样事情的更简洁的方法。
您收到的错误消息可能是因为您正在写入不应该触摸的 memory 部分。 这可能是错误使用“sizeof”的结果。 它返回数字中的元素数量,而不是 memory 大小。 建议检查对实际问题的评论,以获得第二个问题的正确解决方案。
这种排序不起作用,因为您只运行一次数字列表,因此它会交换相邻项目但不会对列表进行排序(它是冒泡排序的一半实现)
我很确定您在这里遇到了运算符优先级问题:
*b++;
事实上,编译器应该警告你一个没有副作用的操作符( *
)。
除此之外,指针b
将 go 离开数组的末尾,因为它从元素 1 开始并且是高级size
倍,它最终将指向numbers[size+1]
。 如果编译器优化了无用的取消引用,那将不是问题,但是在上一次传递中,您调用swap(numbers+size-1, numbers+size)
并注销数组的末尾,从而导致堆栈损坏你检测到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.