【问题标题】:trash output when run a std:: vector<double> code in linux terminal - C++在 Linux 终端中运行 std::vector<double> 代码时的垃圾输出 - C++
【发布时间】:2016-05-01 07:03:40
【问题描述】:

我正在尝试在 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++ 的新手,所以如果有人知道我面临什么,我会很高兴听到这个消息:)

【问题讨论】:

  • 旁注:如果要将向量中的所有元素初始化为一个值,只需在构造函数中进行:std::vector&lt;double&gt; x( nx, 0.0005 );

标签: c++ linux g++ stdvector


【解决方案1】:

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

虽然将&lt;= 更改为&lt; 确实 工作,但它只是使此代码正确。它不会“免疫”您很快再次遇到本质上相同的问题。

另一种选择是使用“基于范围的”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";
}

基于范围的for 循环使得意外尝试访问集合边界之外的访问变得更加困难。

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

【讨论】:

    【解决方案2】:

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

    您要么需要使x 更大,要么将循环编写为

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

    (使用&lt; 而不是&lt;=)。

    【讨论】:

    • 奇怪的是,它实际上确实适用于float 的向量。令人毛骨悚然的未定义行为。
    • “似乎有效。”取消定义行为允许程序做任何事情——包括你所期望的。不要依赖它。
    • @Nooble 区分“似乎有效”和“实际上有效”。
    • @Nooble 如果您坚持要解释为什么它似乎有效:floatdouble 的大小不同。因此内存分配可能不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多