运行 std::vector<double> 代码在 linux 终端时的垃圾输出 - C++

trash output when run a std:: vector<double> code in linux terminal - C++

我正在尝试在 linux 终端上使用 g++ 在 C++ 上编写一个简单的 std::vector 代码,但与终端本身的输出相混淆。

我的代码很简单。

#include <iostream>
#include <vector>

int main()  {
  double xl;
  int nx=5;
  double delta_x;
  int i=0;
  std::vector<double> x(nx);

  for(i=0; i <=nx; i++)  {
    x[i]=0.0005;
    std::cout<<x[i]<<std::endl;
  }
return 0;
}

当我编译时:

$ g++ grid2.cpp -o grid2

成功并给出了一个grid2可执行文件。当我 运行 可执行文件时出现问题:

$ ./grid2

在终端上给我这样的输出:

./grid2[0x400929]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:05 13372783                           /mnt/home/FINALS/codeDNS_AKA_MY_MAIN_DIR/basic_CPP/grid2
00601000-00602000 rw-p 00001000 08:05 13372783                           /mnt/home/FINALS/codeDNS_AKA_MY_MAIN_DIR/basic_CPP/grid2
01f23000-01f55000 rw-p 00000000 00:00 0                                  [heap]
7f13fc000000-7f13fc021000 rw-p 00000000 00:00 0 
7f13fc021000-7f1400000000 ---p 00000000 00:00 0 
7f1403971000-7f1403b0c000 r-xp 00000000 08:06 790319                     /usr/lib/libc-2.22.so
7f1403b0c000-7f1403d0b000 ---p 0019b000 08:06 790319                     /usr/lib/libc-2.22.so
7f1403d0b000-7f1403d0f000 r--p 0019a000 08:06 790319                     /usr/lib/libc-2.22.so
7f1403d0f000-7f1403d11000 rw-p 0019e000 08:06 790319                     /usr/lib/libc-2.22.so
7f1403d11000-7f1403d15000 rw-p 00000000 00:00 0 
7f1403d15000-7f1403d2b000 r-xp 00000000 08:06 790384                     /usr/lib/libgcc_s.so.1
7f1403d2b000-7f1403f2a000 ---p 00016000 08:06 790384                     /usr/lib/libgcc_s.so.1
7f1403f2a000-7f1403f2b000 rw-p 00015000 08:06 790384                     /usr/lib/libgcc_s.so.1
7f1403f2b000-7f1404028000 r-xp 00000000 08:06 790449                     /usr/lib/libm-2.22.so
7f1404028000-7f1404227000 ---p 000fd000 08:06 790449                     /usr/lib/libm-2.22.so
7f1404227000-7f1404228000 r--p 000fc000 08:06 790449                     /usr/lib/libm-2.22.so
7f1404228000-7f1404229000 rw-p 000fd000 08:06 790449                     /usr/lib/libm-2.22.so
7f1404229000-7f140439b000 r-xp 00000000 08:06 790552                     /usr/lib/libstdc++.so.6.0.21
7f140439b000-7f140459b000 ---p 00172000 08:06 790552                     /usr/lib/libstdc++.so.6.0.21
7f140459b000-7f14045a5000 r--p 00172000 08:06 790552                     /usr/lib/libstdc++.so.6.0.21
7f14045a5000-7f14045a7000 rw-p 0017c000 08:06 790552                     /usr/lib/libstdc++.so.6.0.21
7f14045a7000-7f14045ab000 rw-p 00000000 00:00 0 
7f14045ab000-7f14045cd000 r-xp 00000000 08:06 790282                     /usr/lib/ld-2.22.so
7f1404791000-7f1404797000 rw-p 00000000 00:00 0 
7f14047ca000-7f14047cc000 rw-p 00000000 00:00 0 
7f14047cc000-7f14047cd000 r--p 00021000 08:06 790282                     /usr/lib/ld-2.22.so
7f14047cd000-7f14047ce000 rw-p 00022000 08:06 790282                     /usr/lib/ld-2.22.so
7f14047ce000-7f14047cf000 rw-p 00000000 00:00 0 
7ffec8a9b000-7ffec8abc000 rw-p 00000000 00:00 0                          [stack]
7ffec8bef000-7ffec8bf1000 r--p 00000000 00:00 0                          [vvar]
7ffec8bf1000-7ffec8bf3000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

但是(另一个)奇怪的是,当我改变

std::vector<double>

进入

std::vector<float>

那些垃圾都不见了。我可以在我的终端上看到干净的输出。

还有一件事,当我像这样将输出打印到另一个文件时:

$ ./grid2 > test.txt

double 和 float 的结果相同。没有垃圾,干净的输出。这就像垃圾只出现在我的终端上。

我是 linux 和 c++ 的新手,所以如果有人知道我面临的问题,我会很高兴听到:)

x 有 5 个元素。不幸的是,您正在访问 6 - 您的 for 循环给出了从 0 到 5 的 i 值,总共是 6。访问 x[5] 是未定义的行为;如果你幸运的话,它会以明显的方式崩溃,但任何事情都有可能发生。

您要么需要使 x 变大,要么将您的循环写成

for(i=0; i < nx; i++) 

(使用 < 而不是 <=)。

如前所述,您有未定义的行为。

虽然将 <= 更改为 < 确实 有效,但它只是使此代码正确。 "immunize" 你反对 运行 不会很快再次陷入本质上相同的问题。

一种替代方法是像这样使用 "range-based" for 循环:

#include <iostream>
#include <vector>

int main()  {
  double xl;
  int nx=5;
  double delta_x;
  int i=0;
  std::vector<double> x(nx);

  for(double &d : x)  {
    d=0.0005;
    std::cout<<d<<"\n";
  }
}

虽然在这种情况下,您要用所有相同的值填充它,所以最好只这样初始化它:

#include <iostream>
#include <vector>

int main()  {
    std::vector<double> x(5, 0.0005);

    for (double const &d : x)
        std::cout << d << "\n";
}

range-based for 循环使得意外访问集合范围之外的访问变得更加困难。

顺便说一句:注意使用 "\n" 而不是 std::endl。我建议不要在一般情况下使用 std::endl——在极少数情况下您需要它的功能,请使用 std::cout << "\n" << std::flush; 明确说明。在更常见的情况下,您并不真正想要 flush,只需忽略它即可。 endl 两者兼而有之,尽管 flush 几乎从来都不是人们想要的(而且大多数人甚至都不知道它会发生)。