在保存数据的同时使用 C++ 和 Valgrind 使用 strcat 使用的大小为 8 的未初始化值 [英] used uninitialized value of size 8 by strcat using C++ with Valgrind while saving data

查看:31
本文介绍了在保存数据的同时使用 C++ 和 Valgrind 使用 strcat 使用的大小为 8 的未初始化值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道存在关于分段错误的类似帖子,但是,我有一些具体问题需要一些指导.我正在编写代码,它是一个模拟,用于计算一些值并将所有这些值保存在一个文档中,以便稍后用于数据分析.

在调试模式下使用 Valgrind 运行代码时出现分段错误错误,我得到以下信息:

使用了大小为 8 的未初始化值":

迭代 = 100 t=10.1000000==26716== 条件跳转或移动取决于未初始化的值==26716== 在 0x1007F7910:_platform_memmove$VARIANT$Haswell(在/usr/lib/system/libsystem_platform.dylib 中)==26716== 由 0x1005BC91:strcat(在/usr/lib/system/libsystem_c.dylib 中)==26716== by 0x1000031F2: main (ExampleScript.cpp:594)

基本上,它为以下行给出了这个错误:594,599,604 在 for 循环中:

593 字符 KEfilename[5];第594话第595话

和第 604 行:

603 字符文件名[5];第604话第605话

用于保存数据的 for 循环:

printf("Iteration = %d t = %.10f P_iter = %d\n", iter, time[iter+1], P_iter);//保存每个频率时间步长的数据if ((iter/frequency) - saveNumber == 0){c2rfft(Nk, N);c2rfft(KEk, KE);//将main中计算出的KEk复数值转换为实数c2rfft(KIk, KI);c2rfft(Pk, P);字符保存[3];snprintf(save, 3, %d", saveNumber);const char *type = ".txt";字符 Nfilename[5];strcat(Nfilename, N");strcat(Nfilename, 保存);字符 KEfilename[5];strcat(KEfilename, KE");strcat(KEfilename, 保存);字符 KIfilename[5];strcat(KIfilename, KI");strcat(KIfilename,保存);字符文件名[5];strcat(Pfilename, P");strcat(文件名,保存);//print2DArrf: void print2DArrf(char *filename, double *arr)打印2DArrf(N文件名,N);打印2DArrf(KE文件名,KE);打印2DArrf(KI文件名,KI);print2DArrf(Pfilename, P);memset(Nfilename, 0, sizeof Nfilename);memset(KEfilename, 0, sizeof KEfilename);memset(KIfilename, 0, KIfilename 的大小);memset(Pfilename, 0, sizeof Pfilename);saveNumber++;

这是一个循环,我将数据保存为特定文件格式txt".我认为这个问题与初始化"没有关系.因为我对初始化所有内容(包括指针)的方式充满信心.我也确保免费"一切都一样.

分段错误发生在相同的迭代和 t 中,所以这让我质疑我的数据保存方法.另外,我没有任何 C++ 经验,所以很高兴指出我的问题并解释原因.

主要代码示例:

#include#include#include "Functions.h";#include "fftw3.h";#include int main(){//设置参数双倍频率 = 200.0;双 dt = 0.1;双趋势 = 5000.;双 err_max = 1e-7;int P_iter_max = 500;int iter_max = 趋向/dt;int saveNumber = 1;//初始化参数双*N;N = (double*) fftw_malloc(nx*ny*sizeof(double));fftw_complex *Nk;Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex));双*KIk;KIk = (double*) fftw_malloc(nx*ny*sizeof(double));双*KE;KE = (double*) fftw_malloc(nx*ny*sizeof(double));fftw_complex *KEk;KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));双*P;P = (double*) fftw_malloc(nx*ny*sizeof(double));fftw_complex *Pk;pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));//保存ICint P_iter = Potk(invnk, dndxk, dndyk, Pk, PSk, kx, ky, ninvksq, err_max, P_iter_max);for (int iter = 0; iter < iter_max; iter++){//计算一些值//检查收敛//保存 I.C 循环P_iter = Pk(NNk, dndxk, dndyk, phik, potSourcek, kx, ky, ninvksqu, err_max, P_iter_max);双倍时间[iter_max + 1];时间[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);打印2DArrf(KEinitial,KE);打印2DArrf(KIinitial,KI);print2DArrf(Pinitial, P);

解决方案

我认为问题与初始化"无关

你应该另想.

<块引用>

char Nfilename[5];

您已经默认初始化了这个数组.在这种情况下,这意味着内容是不确定的.

<块引用>

strcat(Nfilename, N");

在这里,您将内容不确定的数组传递(指向)strcat.strcat 要求左侧参数是一个包含空终止字符串的数组(并且该数组对于结果字符串来说足够大).您传递的数组不包含以空字符结尾的字符串,因此程序的行为未定义.

您已多次重复此错误.

I am aware of existence of similar posts about segmentation fault, however, I have a bit of a specific issue that I need some guidance with. I am working on a code, it's a simulation that calculates some values and saves all of these values in a document that could be used later for data analysis.

I am getting a segmentation fault error when I run the code with Valgrind in debugging mode I get the following:

"used uninitialized value of size 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)

Basically, it gives this error for the lines: 594,599,604 which are in the for loop:

593         char KEfilename[5];

594         strcat(KEfilename, "KE");
595         strcat(KEfilename, save);

and line 604:

603         char Pfilename[5];
604         strcat(Pfilename, "P");
605         strcat(Pfilename, save);

The for loop to save my data:

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++;


It's a loop where I am saving my data to be written in a specific file format "txt." I don't think the issue has to do with "initializing" since I am sort of confident in the way I initialized everything, including pointers. I also, made sure to "free" everything as well.

The segmentation fault happens at the same iteration and t so that's what made me question my method of data saving. Also, I do not have any experience in c++ so would be nice to point my issues and explain why.

A sample of main code:

#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"

You should think otherwise.

char Nfilename[5];

You've default initialised this array. In this case, that means the contents are indeterminate.

strcat(Nfilename, "N");

Here, you pass (pointer to) that array whose contents are indeterminate into strcat. strcat requires that the left hand argument is an array which contains a null terminated string (and that the array is sufficiently large for the result string). The array that you passed does not contain a null terminated string, and as a result the behaviour of the program is undefined.

You've repeated this bug several times.

这篇关于在保存数据的同时使用 C++ 和 Valgrind 使用 strcat 使用的大小为 8 的未初始化值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆