gpt4 book ai didi

c++ - C++ 程序中的奇怪错误 : Removing Printout Breaks Program

转载 作者:行者123 更新时间:2023-11-30 03:10:11 26 4
gpt4 key购买 nike

这是一个很奇怪的问题...删除下面函数中的 cout 会导致它停止打印正确/预期的结果并打印垃圾值。 (即它仍然运行它输出的数据,但是是错误的)。有什么想法吗?

bool extract_tension(std::vector<double> &interfacial_tension_trap,
std::vector<double> &interfacial_tension_simp,
const std::string data,
const unsigned int num_slabs,
const double z_min, const double z_max)
{

//start @ first number
unsigned int start = 17;
unsigned int end = 17;

std::vector<double> px;
std::vector<double> py;
std::vector<double> pz;

std::vector<double> pn_minus_pt;

double result_simp=0.0;
double result_trap=0.0;

//skip timestep entry
end=get_next_space(start, data);

for(unsigned int counter=0; counter<num_slabs;counter++)
{
start = end+2;

end=get_next_space(start, data);
px.push_back(atof(data.substr(start,(end-start+1)).c_str()));
//skip the space
start = end+2;
end=get_next_space(start, data);
py.push_back(atof(data.substr(start,(end-start+1)).c_str()));
//skip the space
start = end+2;
end=get_next_space(start, data);
pz.push_back(atof(data.substr(start,(end-start+1)).c_str()));

//calculate pressure difference
// WARNING : Unit conversion ahead
// NAMD outputs pressure in bars and distance in Angstroms
// we want an integrated result of mN/m, instead.
// 1 Angstrom = 1e-10 m
// 1 bar = 1e8 mN/m^2
// net conversion -- 1e-2
pn_minus_pt.push_back((pz[counter]-0.5*(px[counter]+py[counter]))*0.01);
std::cout << "Current del_P : "
<< (pz[counter]-0.5*(px[counter]+py[counter]))*0.01
<< std::endl;
}
calculate_trapezoid(pn_minus_pt, num_slabs, z_min, z_max, result_trap);
interfacial_tension_trap.push_back(result_trap);
calculate_simpson(pn_minus_pt, num_slabs, z_min, z_max, result_simp);
interfacial_tension_simp.push_back(result_simp);
}

显然只要用打印语句接触任何 vector 就可以让程序正确执行(即涉及 px、py 或 pz 的打印输出)

完整程序如下:

/*********************************
*
* NAME: Interfacial Tension Calculator
* VERSION: 0.1
* AUTHOR: Jason R. Mick
* GROUP: Wayne State University, Potoff Group
* COPYRIGHT: (c) Jason R. Mick 2010
* DATE: August 9, 2010
*
* CHANGE LOG
* VERSION DATE COMMENTS
*----------------------------------------------------------------------
* 0.1 Aug. 9, 2010 Finished basic code, sans debugging
* 0.5 Aug 10, 2010 Compiled and tested code fixed error in Simpson's
* method where results were being divided rather
* than multiplied.
*
*
* FULL NOTES:
*----------------------------------------------------------------------
* You can compile this program by typing:
* g++ main.cc -o it_util
*
* You can run this program by typing:
* it_util <filename>.log <# slabs> <z-min> <z-max>
*
* where z-min and z-max represent the z-axis boundaries of the system,
* e.g.--
* it_util my_file.log 140 0.0 80.0
*
* This program only works with NAMD *.log file output
* The pressure profile MUST be turned on in your *.conf file
* for the pressure profile info to dump to the *.log file. This
* program requires that info.
*
* This program can handle 1,000+ slabs, but it has a limit to the
* character buffer and thus VERY large slab counts may cause it to fail.
*
* A standard Composite Simpson numerical integration method is used,
* which assumes a non-smooth data set.
*
* The interfacial tension is integrated at each step and then averaged
* so pertinent statistics can be gathered.
*
* You can redirect the output to store the interfacial tension
* statistics as follows:
* it_util <filename>.log <# slabs> <z-min> <z-max> > <my_file>.out
*
*******************************************/

#include <stdio.h>
#include <math.h>

#include <iostream>
#include <vector>
#include <fstream>

#include <sys/stat.h>

//Turn on to enable all interfacial
//tension results to be printed, pre-averaging
//#define DEBUG true

void start_integrations(const std::string filename,
const unsigned int num_slabs,
const double z_min, const double z_max);


int main ( int argc, char *argv[] )
{
struct stat file_info;
std::string filename = argv[1];
int slab_count;
double z_min;
double z_max;

if ( argc != 5 ) /* argc should be 3 for correct execution */
{
/*Print out proper args syntax */
std::cout << "ERROR: Missing arguments!" << std::endl
<< "Proper syntax:" << std::endl
<< "it_util <my_file>.log <# of slabs> <z-coord start>"
<< "<z-coord end>"
<< std::endl;
}
if(stat(argv[1],&file_info)==0)
{
try
{
slab_count = atoi(argv[2]);
if (slab_count > 2)
{
try
{
z_min = atof(argv[3]);
try
{
z_max = atof(argv[4]);
start_integrations(filename,
static_cast<unsigned int>(slab_count),
z_min,
z_max);
}
catch( char * str )
{
/*invalid integer third input*/
std::cout << "Invalid input -- fourth argument was invalid "
<< "decimal number, should be standard " << std::endl
<< "decimal type entry..." << std::endl
<< "I.E." << std::endl
<< "it_util my_file.log 140 0.0 80.0" << std::endl;

}
}
catch( char * str )
{
/*invalid integer third input*/
std::cout << "Invalid input -- third argument was invalid "
<< "decimal number, should be standard " << std::endl
<< "decimal type entry..." << std::endl
<< "I.E." << std::endl
<< "it_util my_file.log 140 0.0 80.0" << std::endl;

}
}
else
{
/*invalid integer secondary input*/
std::cout << "Invalid input -- second argument was invalid integer, "
<< "should be unsigned integer 2 or greater..." << std::endl
<< "I.E." << std::endl
<< "it_util my_file.log 140 0.0 80.0" << std::endl;
}
}
catch( char * str )
{
/*non integer secondary input*/
std::cout << "Invalid input -- second argument was non-integer, "
<< "should be unsigned integer 2 or greater..." << std::endl
<< "I.E." << std::endl
<< "it_util my_file.log 140 0.0 80.0" << std::endl;
}
}
else
{
/*invalid filename case...*/
std::cout << "File " << filename << "does not exist!" << std::endl
<< "Please choose valid file!" << std::endl;
}

return 1;
}

bool calculate_simpson(const std::vector<double> my_values,
const unsigned int num_points,
const double x_min, const double x_max,
double &results)
{
bool ret_val = false;
bool is_even = true;
double h;

if (my_values.size() >= 2)
{
h = (x_max-x_min)/num_points;
results+=my_values.front();
for (unsigned int counter=1; counter<num_points-1;counter++)
{
if (is_even)
{
results+=4*my_values[counter];
}
else
{
results+=2*my_values[counter];
}
is_even = !is_even;
}
results+=my_values.back();
results*=(h/3);
ret_val=true;
}
return ret_val;
}

bool calculate_trapezoid(const std::vector<double> my_values,
const unsigned int num_points,
const double x_min, const double x_max,
double &results)
{
bool ret_val = false;

double x_incr = (x_max-x_min)/(num_points-1);

if (my_values.size() >= 2)
{
for (unsigned int counter=1; counter<num_points-1; counter++)
{
results+=(x_incr/2)*(my_values[counter]+my_values[counter-1]);
}
}
return ret_val;
}

unsigned int get_next_space(const unsigned int start,
const std::string data)
{
unsigned int counter=start;

while (data.length() > counter &&
data.substr(counter,1).compare(" ") != 0)
{
counter++;
}

//if end of string, add one
if ( data.length() == counter)
counter++;
return (counter-1);
}

bool extract_tension(std::vector<double> &interfacial_tension_trap,
std::vector<double> &interfacial_tension_simp,
const std::string data,
const unsigned int num_slabs,
const double z_min, const double z_max)
{

//start @ first number
unsigned int start = 17;
unsigned int end = 17;

std::vector<double> px;
std::vector<double> py;
std::vector<double> pz;

std::vector<double> pn_minus_pt;

double result_simp=0.0;
double result_trap=0.0;

//skip timestep entry
end=get_next_space(start, data);

for(unsigned int counter=0; counter<num_slabs;counter++)
{
start = end+2;

end=get_next_space(start, data);
px.push_back(atof(data.substr(start,(end-start+1)).c_str()));
//skip the space
start = end+2;
end=get_next_space(start, data);
py.push_back(atof(data.substr(start,(end-start+1)).c_str()));
//skip the space
start = end+2;
end=get_next_space(start, data);
pz.push_back(atof(data.substr(start,(end-start+1)).c_str()));

//calculate pressure difference
// WARNING : Unit conversion ahead
// NAMD outputs pressure in bars and distance in Angstroms
// we want an integrated result of mN/m, instead.
// 1 Angstrom = 1e-10 m
// 1 bar = 1e8 mN/m^2
// net conversion -- 1e-2
pn_minus_pt.push_back((pz[counter]-0.5*(px[counter]+py[counter]))*0.01);
std::cout << "Current del_P : "
<< (pz[counter]-0.5*(px[counter]+py[counter]))*0.01
<< std::endl;
}
calculate_trapezoid(pn_minus_pt, num_slabs, z_min, z_max, result_trap);
interfacial_tension_trap.push_back(result_trap);
calculate_simpson(pn_minus_pt, num_slabs, z_min, z_max, result_simp);
interfacial_tension_simp.push_back(result_simp);
}

double average_vector(std::vector<double> my_vector)
{
double average_val=0.0;

for(unsigned int counter=0; counter< my_vector.size(); counter++)
{
average_val+=my_vector[counter]/my_vector.size();
}

return average_val;
}

double std_dev_vector(std::vector<double> my_vector)
{
double std_deviation=0.0;
double average_val = average_vector(my_vector);

for(unsigned int counter=0; counter< my_vector.size(); counter++)
{
std_deviation+=(my_vector[counter]-average_val)*
(my_vector[counter]-average_val);
}
std_deviation=sqrt(std_deviation);

return std_deviation;
}

void start_integrations(const std::string filename,
const unsigned int num_slabs,
const double z_min, const double z_max)
{
std::ifstream in_file;
std::vector<double> interfacial_tension_trap;
std::vector<double> interfacial_tension_simp;
std::string current_line;
char * cstr_line;
bool data_grab_success = true;

in_file.open(filename.c_str(), std::ifstream::in);
while (!in_file.eof() && data_grab_success)
{
cstr_line=(char *) malloc(sizeof(char)*65536);
//get new line
in_file.getline(cstr_line,65536);
current_line = cstr_line;
free(cstr_line);
if (current_line.substr(0,15).compare("PRESSUREPROFILE")==0)
{
//pressure profile found!

//process line to get the interfacial tension, check that it succeeded
data_grab_success = extract_tension(interfacial_tension_trap,
interfacial_tension_simp,
current_line,
num_slabs,
z_min,
z_max);
}
}
in_file.close();

//print stats
std::cout << "Interfacial Tension (Trapezoid Method): "
<< average_vector(interfacial_tension_trap) << std::endl
<< "Standard Deviation (Trapezoid Method): "
<< std_dev_vector(interfacial_tension_trap) << std::endl
<< "Interfacial Tension (Composite Simpson's Method): "
<< average_vector(interfacial_tension_simp) << std::endl
<< "Standard Deviation (Composite Simpson's Method): "
<< std_dev_vector(interfacial_tension_simp) << std::endl;
}

这是一组示例数据:

Removed... see explanation at end of post for link to data to use.

这样编译:

g++ main.cc -o it_util

使用命令运行:

it_util equil2_NVT_PP_318Slabs.log 318 0.0 318.0 > temp.out

仅供引用,在有人评论我的#ifdef“调试”语句之前,请注意它们用于数据转储。我以前用过 GDB。我猜如果我不这么说,有人会评论“学习使用 gdb”。在这种情况下,程序循环了很多次迭代,GDB 没有给我有用的信息,打印输出转储到输出文件 DO。

注意:
事实上,我发现如果你使用被解析文件的精简版本(在上面的数据部分),程序也不会输出正确的数据。当我恢复原始数据文件时它工作了,但是文件太大无法发布在这里(我试过......)所以这不是一个选项......相反,我已经上传了一个完整的 pastebin 到这里: http://pastebin.com/JasbSc7B

最佳答案

我的第一篇文章在这里。很棒的网站。

这当然很神秘。这不是一个答案,而是一组轻率的探索途径,如果您还没有的话:

  1. 您的输入数据(NaN 等)中的某些异常导致 cout 语句中的数学更改 FPU 状态。我无法理解那可能是什么,但听起来您正处于不遗余力的阶段。

  2. 您正在使用的 std::vector<> 的实现中存在奇怪的错误,由您的特定使用模式以某种方式触发,使 operator[] 调用具有改变状态的副作用。通过将 iostream 排除在等式之外并仅调用 operator[] 进行调查。您可以将范围缩小到将事情搞砸的特定调用。但这不太可能。

  3. 描述输出的“不正确性”。垃圾中有什么图案吗?它与正确的输出应该是什么有任何关联吗?

  4. 解决难以理解的错误的常用方法:修剪代码,直到获得最简单的重现案例,对其进行检测以找出第一个错误结果出现的确切时间,等等。

    <
  5. 尝试使用不同的库、编译器、操作系统或 CPU 重现错误。不可能,但你永远不知道,如果仍然重现,至少你已经向自己保证这实际上是你自己的错误,你不会用头撞砖墙。

有些建议比较笼统,但希望对您有所帮助。破解后请告诉我们!

关于c++ - C++ 程序中的奇怪错误 : Removing Printout Breaks Program,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3452355/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com