Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function with pointer argument

I am writing a C++ program that outputs data to a file, generates a python script and calls pyplot to make the plotting.

However, when I pass the arguments in terms of the pointers, it can be compiled properly, but cannot run. It returns error. When I use Xcode debug mode and execute it step by step, it gives correct result by chance but not always. Sometimes it also returns an error.

I doubt that it might be caused by some memory allocation problem, but I cannot identify what is exactly the problem.

My codes are as following:

1) main

#include <iostream>
#include <stdlib.h>
#include <cmath>
#include "PyCPlot.h"

using namespace std;

double pi = 3.1415926;

int main(int argc, const char * argv[]) {

    int nline = 100;

    double * np_list = new double(nline);
    double * pack_fraction_np = new double (nline);

    for (int i=0; i<nline; i++){
        np_list[i] = double(i)/double(nline)*2*pi;
        pack_fraction_np[i] = cos(np_list[i]);
    }

    PyCPlot_data_fout("RandomPacking", nline, np_list, pack_fraction_np);
    PyCPlot_pythonscript("RandomPacking", "Random Packing");
    PyCPlot_pyplot("RandomPacking", "Random Packing");

    return 0;
}

2) head file

#ifndef PyCPlot_h
#define PyCPlot_h

#include <iostream>
#include <cmath>
#include <fstream>
#include <string>
#include <stdlib.h>

using namespace std;


int PyCPlot_data_fout(string datafilename, int nline, double * x, double *y){
    ofstream fout;
    fout.open(datafilename+".txt");
    fout << nline << endl;
    for (int i=0; i<nline; i++){
        fout << x[i] << "  " << y[i] << endl;
    }
    fout.close();
    return 0;
}

int PyCPlot_pythonscript(string datafilename, string plttitle){

    string strhead = "import numpy as np\nimport matplotlib.pyplot as plt\n";
    string strpltfig = "plt.figure()\n";
    string strpltplt = "plt.plot(xlist, ylist)\n";
    string strplttit = "plt.title('"+plttitle+"')\n";
    string strpltshw = "plt.show()\n";

    string strfileopen ="f = open('"+datafilename+".txt', 'r')\n";
    string strreadline ="size = map(int, f.readline().split())\n";
    string strpltlist ="xlist = np.zeros((size))\nylist = np.zeros((size))\n";
    string strfor = "for i in range(size[0]):\n    xlist[i], ylist[i] = map(float, f.readline().split())\n";

    ofstream pyout;
    pyout.open("PyCPlot_"+datafilename+".py");
    pyout << strhead << strfileopen << strreadline << strpltlist << strfor;
    pyout << strpltfig << strpltplt << strplttit << strpltshw;
    pyout.close();
    return 0;
}

int PyCPlot_pyplot(string datafilename, string plttitle){

    string strsystemsh ="source ~/.bashrc; python PyCPlot_"+datafilename+".py";
    system(strsystemsh.c_str());

    return 0;
}

#endif /* PyCPlot_h */

When it is ran, I get below error message

malloc: *** error for object 0x1002002e8: incorrect checksum for freed object - object was probably modified after being freed.
like image 428
Einstein_is_Coding Avatar asked Jul 27 '17 23:07

Einstein_is_Coding


2 Answers

You want to pass an array, so pass an actual array which can be sized at runtime (std::vector), not some random pointer that hopefully will be pointing to the first element of an array (and in this case, it doesn't)

Your mistake is using new double(x) instead of new double[x]. The former allocates a single double with a value equal to x, and the latter allocates an array of double of size x and returns a pointer to the first element, but, as I've said, you wouldn't have that problem at all had you actually used std::vector and not dabbled with pointers like the early 90s style (not to mention, you wouldn't have a memory leak had you used std::vector).

like image 92
milleniumbug Avatar answered Sep 30 '22 00:09

milleniumbug


You're doing a few things which are not right or seem strange.

The code new double(nline) will allocate a single double with the value of nline, which doesn't seem what you intend. It looks like you intend to dynamically allocate an array of double. Actually from the code you've shown there's no reason you can't do a simple array as the size is known at compile time.

This code below:

double * np_list = new double(nline);
double * pack_fraction_np = new double (nline);

Could be replaced with:

double np_list[nline];
double pack_fraction_np[nline];
like image 45
MrJLP Avatar answered Sep 30 '22 01:09

MrJLP