C++ strcat使用C++;在保存数据时使用Valgrind
我知道存在类似的关于分段错误的帖子,但是,我有一个具体的问题,我需要一些指导。我正在编写一个代码,它是一个模拟,计算一些值,并将所有这些值保存在一个文档中,以便以后用于数据分析 在调试模式下使用Valgrind运行代码时,我遇到了一个分段错误,我得到以下结果: “已使用大小为8的未初始化值”: 基本上,它为for循环中的行594599604给出了此错误:C++ strcat使用C++;在保存数据时使用Valgrind,c++,valgrind,C++,Valgrind,我知道存在类似的关于分段错误的帖子,但是,我有一个具体的问题,我需要一些指导。我正在编写一个代码,它是一个模拟,计算一些值,并将所有这些值保存在一个文档中,以便以后用于数据分析 在调试模式下使用Valgrind运行代码时,我遇到了一个分段错误,我得到以下结果: “已使用大小为8的未初始化值”: 基本上,它为for循环中的行594599604给出了此错误: 593 char KEfilename[5]; 594 strcat(KEfilename, "K
593 char KEfilename[5];
594 strcat(KEfilename, "KE");
595 strcat(KEfilename, save);
第604行:
603 char Pfilename[5];
604 strcat(Pfilename, "P");
605 strcat(Pfilename, save);
用于保存我的数据的for循环:
printf("Iteration = %d t = %.10f P_iter = %d\n", iter, time[iter+1], P_iter);
// Save data every frequency time steps
if ((iter/frequency) - saveNumber == 0){
c2rfft(Nk, N);
c2rfft(KEk, KE); //convert complex values of KEk calculated in main to real
c2rfft(KIk, KI);
c2rfft(Pk, P);
char save[3];
snprintf(save, 3, "%d", saveNumber);
const char *type = " .txt";
char Nfilename[5];
strcat(Nfilename, "N");
strcat(Nfilename, save);
char KEfilename[5];
strcat(KEfilename, "KE");
strcat(KEfilename, save);
char KIfilename[5];
strcat(KIfilename, "KI");
strcat(KIfilename, save);
char Pfilename[5];
strcat(Pfilename, "P");
strcat(Pfilename, save);
//print2DArrf: void print2DArrf(char *filename, double *arr)
print2DArrf(Nfilename, N);
print2DArrf(KEfilename, KE);
print2DArrf(KIfilename, KI);
print2DArrf(Pfilename, P);
memset(Nfilename, 0, sizeof Nfilename);
memset(KEfilename, 0, sizeof KEfilename);
memset(KIfilename, 0, sizeof KIfilename);
memset(Pfilename, 0, sizeof Pfilename);
saveNumber++;
这是一个循环,在这个循环中,我将数据保存到一个特定的文件格式“txt”中。我不认为问题与“初始化”有关,因为我对初始化所有内容(包括指针)的方式有点信心。我还确保“免费”所有东西
分段错误发生在同一次迭代中,所以这就是我质疑我的数据保存方法的原因。另外,我没有任何C++经验,所以很好地指出我的问题并解释原因。
主要代码示例:
#include<math.h>
#include<stdio.h>
#include "Functions.h"
#include "fftw3.h"
#include <cstring>
int main(){
// Setting parameters
double frequency = 200.0;
double dt = 0.1;
double tend = 5000.;
double err_max = 1e-7;
int P_iter_max = 500;
int iter_max = tend / dt;
int saveNumber = 1;
//Initialize Parameters
double *N;
N = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Nk;
Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex));
double *KIk;
KIk = (double*) fftw_malloc(nx*ny*sizeof(double));
double *KE;
KE = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *KEk;
KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
double *P;
P = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Pk;
Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
//Save I.Cs
int P_iter = Potk(invnk, dndxk, dndyk, Pk, PSk, kx, ky, ninvksq, err_max, P_iter_max);
for (int iter = 0; iter < iter_max; iter++){
// calculate some values
//Check for convergence
// Save I.C loop
P_iter = Pk(NNk, dndxk, dndyk, phik, potSourcek, kx, ky, ninvksqu, err_max, P_iter_max);
double time[iter_max + 1];
time[0] = 0;
c2rfft(Nk, N);
c2rfft(KEk, KE);
c2rfft(KIk, KI);
c2rfft(Pk, P);
char Ninitial[] = "N_initial.txt";
char KEinitial[] = "KE_initial.txt";
char KIinitial[] = "KI_initial.txt";
char Pinitial[] = "P_initial.txt";
print2DArrf(Ninitial, N);
print2DArrf(KEinitial, KE);
print2DArrf(KIinitial, KI);
print2DArrf(Pinitial, P);
#包括
#包括
#包括“Functions.h”
#包括“fftw3.h”
#包括
int main(){
//设置参数
双频=200.0;
双dt=0.1;
双倍趋势=5000。;
双误差最大值=1e-7;
int P_iter_max=500;
int iter_max=倾向/dt;
int saveNumber=1;
//初始化参数
双*N;
N=(双*)fftw_malloc(nx*ny*sizeof(双));
fftw_复合体*Nk;
Nk=(fftw_复合体*)fftw_malloc(nx*nyk*sizeof(fftw_复合体));
双*KIk;
KIk=(双*)fftw_malloc(nx*ny*sizeof(双));
双*克;
KE=(双*)fftw_malloc(nx*ny*sizeof(双));
fftw_综合体*KEk;
KEk=(fftw_复合体*)fftw_malloc(nx*nyk*sizeof(fftw_复合体));
双*P;
P=(双*)fftw_malloc(nx*ny*sizeof(双));
fftw_复合体*Pk;
Pk=(fftw_复合体*)fftw_malloc(nx*nyk*sizeof(fftw_复合体));
//保存I.C
int P_iter=Potk(invnk、dndxk、dndyk、Pk、PSk、kx、ky、ninvksq、err_max、P_iter_max);
对于(int-iter=0;iter
我认为这个问题与“初始化”无关
你不应该这样想
您已默认初始化此数组。在本例中,这意味着内容不确定
这里,将内容不确定的数组(指针指向)传递到strcat
strcat
中,要求左侧参数是包含以null结尾的字符串的数组(并且数组对于结果字符串足够大)。传递的数组不包含以null结尾的字符串,因此程序的行为未定义
您已多次重复此错误
我认为这个问题与“初始化”无关
你不应该这样想
您已默认初始化此数组。在本例中,这意味着内容不确定
这里,将内容不确定的数组(指针指向)传递到strcat
strcat
中,要求左侧参数是包含以null结尾的字符串的数组(并且数组对于结果字符串足够大)。传递的数组不包含以null结尾的字符串,因此程序的行为未定义
<>你已经多次重复这个bug。 你可以通过简单的使用C++字符串来节省很多麻烦。 这样你就可以写作了
print2DArrf(Nfilename, std::string("N") + std::to_string(saveNumber) + ".txt");
(这将要求您更改print2darf
以获取std::string
(或常量引用)
<>你不说你使用的是哪个版本的C++,所以如果你是旧的C++,,你可能需要使用除<代码>之外的其他东西。
上一篇评论,Valgrind在MaOS上的支持不太好,所以谨慎使用它。
你可以通过简单的使用C++字符串来节省很多麻烦。 这样你就可以写作了print2DArrf(Nfilename, std::string("N") + std::to_string(saveNumber) + ".txt");
(这将要求您更改print2darf
以获取std::string
(或常量引用)
<>你不说你使用的是哪个版本的C++,所以如果你是旧的C++,,你可能需要使用除<代码>之外的其他东西。
最后一点意见是,macOS上的Valgrind不太受支持,因此请谨慎使用。一些数组不够大,无法容纳您复制到它们的数据,并且没有初始化。请尝试
char-KEfilename[16]={0};
其余部分也一样。数字是任意的,但您现在拥有的太短了。您需要为字符总数+1留出空间。您可以使用snprintf
来构造每个名称,避免重复的strcat
。我对这一点相当陌生。不确定如何使用snprintf来为总字符构造每个名称racters?尤其是save?这非常有用。有些数组不够大,无法容纳您复制到它们的数据,而且它们没有初始化。请尝试char-KEfilename[16]={0};
,其余的都一样。这个数字是任意的,但您现在拥有的太短。您需要为字符总数+1留出空间。
strcat(Nfilename, "N");
print2DArrf(Nfilename, std::string("N") + std::to_string(saveNumber) + ".txt");