带有指针参数的 C++ 函数

Posted

技术标签:

【中文标题】带有指针参数的 C++ 函数【英文标题】:C++ function with pointer argument 【发布时间】:2018-01-03 21:02:52 【问题描述】:

我正在编写一个将数据输出到文件的 C++ 程序,生成 python 脚本并调用 pyplot 进行绘图。

但是,当我根据指针传递参数时,它可以正确编译,但无法运行。它返回错误。当我使用 Xcode 调试模式 并逐步执行它时,它会偶然给出正确的结果,但并非总是如此。有时它也会返回错误。

我怀疑这可能是由一些内存分配问题引起的,但我无法确定究竟是什么问题。

我的代码如下:

1) 主要

#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) 头文件

#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 */

当它运行时,我收到以下错误消息

malloc: *** error for object 0x1002002e8: incorrect checksum for freed object - object was probably modified after being freed.

【问题讨论】:

您是否正在尝试为 ios 构建,可以看看这个链接***.com/questions/19840671/… 主要是您的代码没有看到任何免费调用,请您提及您的平台 [OT]:您应该避免使用using namespace std;,尤其是在标题中。 [OT]:你应该标记inline header 中定义的函数,以便能够将你的 header 包含在几个 cpp 文件中。 【参考方案1】:

你想传递一个数组,所以传递一个可以在运行时调整大小的实际数组(std::vector),而不是一些希望指向数组第一个元素的随机指针(在这种情况下,它没有)

您的错误是使用new double(x) 而不是new double[x]。前者分配一个值等于xdouble,后者分配一个大小为xdouble 数组并返回一个指向第一个元素的指针,但是,正如我所说,你如果您实际使用 std::vector 并且不涉足 90 年代早期风格的指针(更不用说,如果您使用 std::vector,您不会出现内存泄漏),那么根本不会有这个问题。

【讨论】:

有理由避免使用vector,但即便如此,您也应该使用unique_ptr&lt;T[]&gt; 或其他名称。其中大部分原因是性能开销,使用 Python 完全相形见绌。【参考方案2】:

您正在做一些不正确或看起来很奇怪的事情。

代码new double(nline) 将分配一个值为nline 的double,这似乎不是您想要的。 看起来您打算动态分配 double 数组。实际上,从您展示的代码来看,没有理由不能做一个简单的数组,因为大小在编译时是已知的。

这段代码如下:

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

可以替换为:

double np_list[nline];
double pack_fraction_np[nline];

【讨论】:

最好将nline 声明为constexpr 那或std::array&lt;double, nline&gt; 最好 if 它将保持编译时常量,但如果它只是设置为调试它并没有真正帮助. 请注意,由于nline 是一个函数参数,因此使用double np_list[nline]; 依赖于非标准的gcc 扩展(VLA)。 std::vector&lt;double&gt; np_list(nline); 将在所有符合标准的 C++ 编译器中可靠地工作。【参考方案3】:

以下行为np_listpack_fraction_np 分配一个双精度:

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

因此,当您进入循环时,您会将数据写入无效的内存块。您必须使用方括号来定义数组(我没有收到任何错误;使用 clang++)。

考虑使用std::vectorclass。这是一个示例(您的示例),其中doublestd::pair 嵌套在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;

【讨论】:

以上是关于带有指针参数的 C++ 函数的主要内容,如果未能解决你的问题,请参考以下文章

提升 C++。将带有签名指针的成员函数指针传递给函数

无法在 VB.NET 中使用带有来自 Visual C++ DLL 的指针参数的函数

带有函数指针和引用的模板参数推导[重复]

带有模板的 C++ 函数指针

在 C++ 中使用指针和指向指针参数的指针创建构造函数

C++ CreateThread函数如何传递this指针作为参数