使用指向数组的指针遍历对象数组

时间:2018-11-15 05:13:06

标签: c++ arrays pointers c++98

我是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 questionsthis,但到目前为止没有成功。

2 个答案:

答案 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的名字发生冲突。