我是C ++的新手,正在使用C ++ 98进行作业。我正在尝试使用指向数组的指针遍历对象数组。
它正确打印了第一个点,然后打印了一些值。
以下是代码段:
struct Point { int x, y; };
int randomNumber(int low, int high ) {
int randomNumber = low + (rand())/ (RAND_MAX/(high-low));
cout << setprecision(2);
return randomNumber;
}
Point *generateCoordinates(int nodesPerBlock) {
Point cities[nodesPerBlock];
for (int i = 0; i < nodesPerBlock; i++) {
cities[i].x = randomNumber(1, 50);
cities[i].y = randomNumber(1, 50);
}
return cities;
}
int main() {
int nodesPerBlock = 5;
Point *points = generateCoordinates(nodesPerBlock);
for (int n = 0; n < (nodesPerBlock-2); n++) {
cout << "n: x=" << points[n].x << ", y=" << points[n].y << endl;
cout << "n+1: x=" << points[n+1].x << ", y=" << points[n+1].y << endl;
}
}
此打印:
n: x=1, y=4
n+1: x=18, y=11
n: x=2049417976, y=32767
n+1: x=2049417976, y=32767
n: x=2049417976, y=32767
n+1: x=2049417984, y=167804927
实际打印的积分为:
Point : x=1, y=4.
Point : x=18, y=11.
Point : x=13, y=6.
Point : x=2, y=16.
Point : x=16, y=22.
引用了this questions和this,但到目前为止没有成功。
答案 0 :(得分:1)
cities[nodesPerBlock]
是generateCoordinates
函数中的局部变量,当函数退出时它会超出范围。
您正在返回一个地址,并正在main
中访问该地址。这样做是未定义的行为。
您必须使用cities
在堆上分配new
(因为您使用的是C ++ 98),然后将该地址返回给main。然后,您将能够可靠地访问该地址。
处理完后,不要忘记删除在main
末尾分配的内存。
通过将函数更改为采用可以从main
传递的额外参数,可以避免内存分配和删除。那么cities
可以是堆栈中Point
的数组。
void generateCoordinates(Point cities[], int nodesPerBlock);
答案 1 :(得分:0)
您的代码中存在三个错误:
在generateCoordinates
中,声明一个数组cities
,其大小由参数nodesPerBlock
确定。这是不允许的,因为c ++禁止声明可变长度的数组。当您拥有大小可变的数组时,必须显式分配内存。虽然,由于gnu扩展(如果您使用的是gcc),代码可能仍可以编译,但仍未遵循标准。
在generateCoordinates
中,返回一个指向局部变量cities
的指针,该局部变量在退出函数后被释放。这就是为什么您获得随机数的原因。
您忘了包含相关的标题。
正确的方法是:
在main()
将其指针传递到generateCoordinates
此外,不要忘记取消分配数组
代码示例:
#include <cstdlib>
#include <iomanip>
#include <iostream>
struct Point { int x, y; };
int randomNumber(int low, int high ) {
int randomNumber = low + (rand())/ (RAND_MAX/(high-low));
std::cout << std::setprecision(2);
return randomNumber;
}
void generateCoordinates(int nodesPerBlock, Point *cities) {
for (int i = 0; i < nodesPerBlock; i++) {
cities[i].x = randomNumber(1, 50);
cities[i].y = randomNumber(1, 50);
}
}
int main() {
int nodesPerBlock = 5;
Point *points = new Point[nodesPerBlock];
generateCoordinates(nodesPerBlock, points);
for (int n = 0; n < (nodesPerBlock-2); n++) {
std::cout << "n: x=" << points[n].x << ", y=" << points[n].y << std::endl;
std::cout << "n+1: x=" << points[n+1].x << ", y=" << points[n+1].y << std::endl;
}
delete[] points;
}
最后的评论:在代码的标头部分中,应避免使用using namespace std
,因为如果您将标头分成一个单独的文件,则每次包含它时,您都会带出{ {1}}进入全球空间,因此可能与其他std
的名字发生冲突。