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

Posted

技术标签:

【中文标题】为啥这段代码不打印我的数组?【英文标题】:Why isn't this code printing my array?为什么这段代码不打印我的数组? 【发布时间】:2011-08-15 18:11:15 【问题描述】:

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


【问题讨论】:

和主说:整数应该永远是4... sigh,使用sizeof(int)。 int size = sizeof(numbers) / sizeof(int); 上述两种解决方案都不是最优的。更好:size_t size = sizeof numbers / sizeof numbers[0]; 【参考方案1】:

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

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

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

【讨论】:

为什么有两个索引?如果他想要一个计数环,他应该使用一个计数环。即for(int i(0); i &lt; size; ++i) cout &lt;&lt; numbers[i] &lt;&lt; endl; 这也行……我只是指出他的代码中的一个错误,以及一个快速修复它的方法,它只增加了两个字符。【参考方案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"));

【讨论】:

支持 STL。顺便说一句,他还可以使用 std::set 容器并将整个程序缩减到 2 行。【参考方案3】:

我很确定您在这里遇到了运算符优先级问题:

*b++;

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

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

【讨论】:

【参考方案4】:

嗯,我立即跳出来的一件事是你永远不会增加 numToPrint,所以它会打印出 numbers[0],size 次数。

我会把你的印刷部分改写成

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

这样您就可以摆脱代码的打印结果部分,因为上面是做同样事情的更简洁的方法。

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

【讨论】:

请注意,这是 OP 报告的两个错误之一;) 嘿,是的,只是解决了我确定看到的一件事,继续编辑以回答这两个问题,解决了错误使用 sizeof 转到 yi_H 的方法。【参考方案5】:

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

【讨论】:

sizeof numbers 是以字节为单位的大小,而不是元素。除以元素的大小是正确的(应该计算,例如sizeof numbers[0] 好吧,在它锁定之前,我太慢了,无法取消投票。不过,您的回答仍然没有真正回答问题。

以上是关于为啥这段代码不打印我的数组?的主要内容,如果未能解决你的问题,请参考以下文章

检查数组是不是具有特定字符,为啥我的代码不起作用?

为啥这段代码不简单地打印字母 A 到 Z?

为啥代码不能打印这个二维数组的元素?

为啥我的动态数组可以在不调整大小的情况下工作? [复制]

为啥我的函数在 python 中没有打印 [重复]

为啥我不能在我的结构中打印名称?