为什么这段代码不打印我的数组?

时间:2011-08-15 18:11:15

标签: c++ arrays pointers loops

我有一个整数数组排序程序,但是我有一个问题:每当我运行程序时,我有时会得到一个“变量'数字'周围的堆栈已损坏”消息,有时它只是重复打印出数字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");

}

5 个答案:

答案 0 :(得分:2)

首先,您永远不会增加numToPrint,因此您永远不会打印超过numbers[0]的值。至少将您的代码更改为:

while(loopIterator < size){
    cout << numbers[numToPrint++] << endl;
    loopIterator++;
}

其次,由于您的while循环使用了测试i < size,因此在循环的最后一次迭代中,您将访问numbers以外的内存{{1}指针,并可能将该值交换到b的最后一个槽(即numbers指向的位置)。您希望将测试更改为a以避免出现这种情况。例如,如果在i < (size - 1)您有i == 0a = &numbers[0],那么到b = &numbers[1]时,您最终会得到i == 12和{{ 1}} ... a = &numbers[12]在此实例中指向的值超过了数组的末尾。根据编译器设置堆栈的方式以及在堆栈上分配b = &numbers[13]的方式,如果最终b指向激活记录,这实际上可能对您的程序造成一定的破坏您的numbers函数的数据结构,并反过来破坏它。

答案 1 :(得分:2)

我假设您正在将数组排序实现为练习。这并没有真正回答你的问题,但我认为我会发布以供参考,无论如何。这是使用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"));
}

答案 2 :(得分:0)

有一件事立即跳出来就是你永远不会增加numToPrint所以它会打印出数字[0],大小次数。

我会将您的打印部分重写为

for (int i = 0; i < size; i++)
    cout << numbers[i] << endl;

有了这个,您就可以摆脱代码的打印结果部分,因为上面是一种更干净的方式来做同样的事情。

您收到的错误消息可能是因为您正在写入您不应该触摸的内存部分。这可能是因为错误地使用“sizeof”造成的。它返回数字中的元素数,而不是内存大小。建议检查实际问题的评论,以便正确解决第二个问题。

答案 3 :(得分:0)

这种排序不起作用,因为你只运行一次数字列表,所以它会交换相邻的项目,但它不会对列表进行排序(它是泡泡排序的一半实现)

答案 4 :(得分:0)

我很确定你在这里有一个运算符优先级问题:

*b++;

事实上,编译器应该警告你一个没有副作用的运算符(*)。

除此之外,指针b将离开数组的末尾,因为它从元素1开始并且提前size次,它最终将指向numbers[size+1]。如果编译器优化掉无用的解除引用,那就不会有问题了,但是在上一次传递中你调用swap(numbers+size-1, numbers+size)并注销数组的末尾,导致你检测到堆栈损坏。