2016-01-25 2 views
1

Я пытаюсь сделать простой std :: векторный код на C++ с g ++ на linux-терминале, но запутался с выходом на самом терминале.выход мусора при запуске std :: vector <double> код в linux terminal - C++

Мой код прост.

#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 

Это удалось, и дает СЕТКА2 исполняемый файл. Проблема возникает, когда я запустить исполняемый файл:

$ ./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 

результаты одинаковы для обоих двойных и поплавком. Нет мусора, чистый выход. Это похоже на трюк, который появляется только на моем терминале.

Я новичок на Linux и C++, поэтому, пожалуйста, если кто-нибудь знает, что я столкнулся, я буду очень рад услышать, что :)

+1

Примечание: если вы хотите инициализировать все элементы в векторе значением, просто сделайте это в конструкторе: 'std :: vector x (nx, 0.0005);' – paddy

ответ

3

Как уже отмечалось, у вас есть неопределенное поведение.

Хотя изменение <= на <делает Работает, он просто делает этот код правильным. Он не «иммунизирует» вас от того, что вы снова столкнетесь с одной и той же проблемой.

Одним из вариантов было бы использовать «диапазона на основе» 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 << "\n" << std::flush;. В гораздо более распространенном случае, когда вы действительно не хотели этого flush, просто опустите его. endl делает оба, хотя flush почти не нужен (и большинство людей не знают, что это даже случается).

3

x имеет 5 элементов. К сожалению, вы получаете доступ к 6 - ваш цикл for дает значения i от 0 до 5 включительно, что составляет в общей сложности 6. Доступ к x[5] - неопределенное поведение; если вам повезет, он рухнет очевидным образом, но все может произойти.

Вам необходимо либо сделать x больше, или написать свой цикл, как

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

(с использованием <, а не <=).

+0

Странно, это действительно работает с вектором 'float'. Призрачное неопределенное поведение. – Nooble

+0

«Появляется на работе». Неопределенное поведение позволяет программе делать что-либо - в том числе и то, что вы ожидаете. Не полагайтесь на это. –

+1

@Nooble Distinguish «кажется, работа» и «действительно работает». –