为啥这段代码不打印我的数组?
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 < 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()
函数,并反过来破坏它。
【讨论】:
为什么有两个索引?如果他想要一个计数环,他应该使用一个计数环。即for(int i(0); i < size; ++i) cout << numbers[i] << 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]
)
好吧,在它锁定之前,我太慢了,无法取消投票。不过,您的回答仍然没有真正回答问题。以上是关于为啥这段代码不打印我的数组?的主要内容,如果未能解决你的问题,请参考以下文章