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 create a graph.

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

I doubt that this may be caused by some memory allocation problem, but I cannot determine what the problem is.

My codes are as follows:

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) header 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 running, I get below error message

 malloc: *** error for object 0x1002002e8: incorrect checksum for freed object - object was probably modified after being freed. 
+5
source share
3 answers

You want to pass an array, so pass in the actual array, the size of which can be determined at runtime ( std::vector ), and not some random pointer, which, we hope, will point to the first element of the array (and in this case it does not)

Your mistake is to use new double(x) instead of new double[x] . The first one selects a double with a value equal to x , and the last one allocates a double array of size x and returns a pointer to the first element, but, as I said, you would not have this problem at all if you actually used std::vector and didn’t deal with pointers such as the style of the early 90s (not to mention that you would not have a memory leak if you used std::vector ).

+4
source

You are doing a few things that are wrong or seem strange.

In the code new double(nline) one double number with a value of nline will be selected, which does not look the way you expect. It looks like you intend to dynamically allocate an array of two. In fact, from the code you provided, there is no reason why you cannot make a simple array, since the size is known at compile time.

This code is below:

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

It can be replaced by:

 double np_list[nline]; double pack_fraction_np[nline]; 
+3
source

The following lines highlight one double for np_list and pack_fraction_np :

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

As a result, when you enter your loop, you will write data to invalid memory blocks. You should use square brackets to define the array (I am not getting any errors using clang ++).

Consider using the std::vector class. Here is an example (your example) with std::pair of double nested in std::vector :

PyCPlot.h

 #ifndef PyCPlot_h #define PyCPlot_h #include <iostream> #include <cmath> #include <fstream> #include <string> #include <stdlib.h> #include <vector> #include <utility> using namespace std; int PyCPlot_data_fout(string datafilename, std::vector<std::pair<double, double>>& v){ ofstream fout; fout.open(datafilename+".txt"); fout << v.size() << endl; for (int i=0; i < v.size(); i++){ fout << v[i].first << " " << v[i].second << 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 */ 

PyCPlot.cpp

 #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; std::vector<std::pair<double, double>> v; v.reserve(nline); double a; for (int i=0; i < nline; i++){ a = double(i)/double(nline)*2*pi; v.push_back(std::make_pair(a, cos(a))); } PyCPlot_data_fout("RandomPacking", v); PyCPlot_pythonscript("RandomPacking", "Random Packing"); PyCPlot_pyplot("RandomPacking", "Random Packing"); return 0; } 
0
source

Source: https://habr.com/ru/post/1270300/


All Articles