strcat 在保存数据时使用 C++ 和 Valgrind 使用大小为 8 的未初始化值
used uninitialized value of size 8 by strcat using C++ with Valgrind while saving data
我知道存在关于分段错误的类似帖子,但是,我有一些具体问题需要一些指导。我正在编写一个代码,它是一个模拟,计算一些值并将所有这些值保存在一个文档中,以后可以用于数据分析。
当我在调试模式下使用 Valgrind 运行 代码时,我得到了一个分段错误错误,我得到以下信息:
“使用了大小为 8 的未初始化值”:
Iteration = 100 t=10.1000000
==26716== conditional jump or move depends on uninitialised value(s)
==26716== at 0x1007F7910: _platform_memmove$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==26716== by 0x1005BC91: strcat (in /usr/lib/system/libsystem_c.dylib)
==26716== by 0x1000031F2: main (ExampleScript.cpp:594)
基本上,它给出了以下行的错误:for 循环中的 594,599,604:
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”写入的数据。我认为问题与“初始化”无关,因为我对初始化所有内容(包括指针)的方式很有信心。我也确保“释放”所有内容。
分段错误发生在同一次迭代和 t 中,所以这就是让我质疑我的数据保存方法的原因。另外,我没有任何 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);
I don't think the issue has to do with "initializing"
你应该不这么想。
char Nfilename[5];
你已经默认初始化了这个数组。在这种情况下,这意味着内容是不确定的。
strcat(Nfilename, "N");
在这里,您将内容不确定的数组(指向)传递给 strcat
。 strcat
要求左侧参数是一个数组,其中包含以空字符结尾的字符串(并且该数组对于结果字符串来说足够大)。您传递的数组不包含以空字符结尾的字符串,因此程序的行为未定义。
您已多次重复此错误。
只需使用 C++ 字符串即可省去很多麻烦。
所以你可以这样写
print2DArrf(Nfilename, std::string("N") + std::to_string(saveNumber) + ".txt");
(这需要您更改 print2DArrf
以获取 std::string
(或对一个的 const 引用)。
您没有说明您使用的是哪个版本的 C++,因此如果是旧 C++,您可能需要使用 to_string
以外的其他版本。
最后评论,macOS 上的 Valgrind 没有得到很好的支持,因此请谨慎使用。
我知道存在关于分段错误的类似帖子,但是,我有一些具体问题需要一些指导。我正在编写一个代码,它是一个模拟,计算一些值并将所有这些值保存在一个文档中,以后可以用于数据分析。
当我在调试模式下使用 Valgrind 运行 代码时,我得到了一个分段错误错误,我得到以下信息:
“使用了大小为 8 的未初始化值”:
Iteration = 100 t=10.1000000
==26716== conditional jump or move depends on uninitialised value(s)
==26716== at 0x1007F7910: _platform_memmove$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==26716== by 0x1005BC91: strcat (in /usr/lib/system/libsystem_c.dylib)
==26716== by 0x1000031F2: main (ExampleScript.cpp:594)
基本上,它给出了以下行的错误:for 循环中的 594,599,604:
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”写入的数据。我认为问题与“初始化”无关,因为我对初始化所有内容(包括指针)的方式很有信心。我也确保“释放”所有内容。
分段错误发生在同一次迭代和 t 中,所以这就是让我质疑我的数据保存方法的原因。另外,我没有任何 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);
I don't think the issue has to do with "initializing"
你应该不这么想。
char Nfilename[5];
你已经默认初始化了这个数组。在这种情况下,这意味着内容是不确定的。
strcat(Nfilename, "N");
在这里,您将内容不确定的数组(指向)传递给 strcat
。 strcat
要求左侧参数是一个数组,其中包含以空字符结尾的字符串(并且该数组对于结果字符串来说足够大)。您传递的数组不包含以空字符结尾的字符串,因此程序的行为未定义。
您已多次重复此错误。
只需使用 C++ 字符串即可省去很多麻烦。
所以你可以这样写
print2DArrf(Nfilename, std::string("N") + std::to_string(saveNumber) + ".txt");
(这需要您更改 print2DArrf
以获取 std::string
(或对一个的 const 引用)。
您没有说明您使用的是哪个版本的 C++,因此如果是旧 C++,您可能需要使用 to_string
以外的其他版本。
最后评论,macOS 上的 Valgrind 没有得到很好的支持,因此请谨慎使用。