2011-08-15 124 views
1

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

} 
+7

and the Lord said:should integers always be 4 ... * sigh *,use sizeof(int)。 –

+1

'int size = sizeof(numbers)/ sizeof(int);' – KevinDTimm

+4

上述两种解决方案都不是最理想的。更好:'size_t size = sizeof numbers/sizeof numbers [0];' –

回答

2

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

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

其次,由于您的while循环使用测试i < size,你是,在循环的最后一次迭代,去的numbers以外的地方存取存储器来储存b指针,并且可能将该值交换到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()函数的激活记录数据结构,这实际上可能会对你的程序造成一些破坏,并反过来腐蚀它。

+2

为什么有两个索引?如果他想要一个计数循环,他应该使用一个计数循环。也就是说'for(int i(0); i AJG85

+1

这也行得通......我只是指出了他的代码中的一个错误,快速的方法来解决它只能增加两个字符。 – Jason

0

好一两件事,立即跳出我的是,你永远不会递增numToPrint所以它会打印出号码[0],大小的次数。

我会重写你的印刷部,

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

有了,你可以摆脱你的代码的打印结果部分,因为上面是做同样的事情的更清洁的方式。

您正在收到的错误信息可能是因为您正在写入您不应触及的部分内存。这可能是错误地使用“sizeof”的结果。它返回数字元素的数量,而不是内存大小。建议您检查实际问题的意见,以便正确解决第二个问题。

+0

请注意,这是OP报告的两个错误之一;) – KevinDTimm

+0

嘿,是的,只是解决了我所看到的一件事,然后继续并编辑回答这两个问题,解决不正确使用sizeof去yi_H。 –

0

这种类型将无法正常工作,你只能通过你的号码清单运行一次,所以它会交换相邻的项目,但它不会对列表进行排序

+0

'sizeof numbers'是以字节为单位测量的大小,而不是元素。除以元素的大小是正确的(并且它应该被计算,例如'sizeof numbers [0]') –

+0

@Ben - 在您的downvote之前修正,请注意OP – KevinDTimm

+0

的评论嗯,我太慢了,无法取消downvote然后锁定。您的答案仍然不能真正回答问题。 –

0
(冒泡排序的半实现它的那种)

我敢肯定你有一个运算符优先级问题就在这里:

*b++; 

事实上,编译器应该警告你有关,没有副作用(在*)操作。

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

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")); 
} 
+0

YAY for STL。在旁注中,他也可以使用'std :: set'容器并将整个程序下载到2行。 – AJG85

+0

@ AJG85:STL确实规则:)。 'std :: set'上的好点。 – Void