【问题标题】:C Segmentation fault in struct. Code translated from Matlab->C with Matlab CoderC 结构中的分段错误。使用 Matlab Coder 从 Matlab->C 翻译的代码
【发布时间】:2013-12-06 10:54:17
【问题描述】:

我正在使用 Matlab Coder 将一些 Matlab 函数转换为 C。一切正常,我想从我的函数返回一个数组(转置向量)。

在 Matlab 中我有一个函数:

function returnedArray = myFun(input arguments)
<function code>

对 C 中函数的调用被转换为:

void myFun(input arguments, emxArray_realT *returnedArray)
<function code>

emxArray_real_T 是一个结构体,由 Matlab Coder 生成:

struct emxArray_real_T
{
    real_T *data;
    int32_T *size;
    int32_T allocatedSize;
    int32_T numDimensions;
    boolean_T canFreeData;
};

而real_T、int32_T...都是创建泛型类型定义:

typedef double real_T;

我从 main 中称它为 myFun:

struct emxArray_real_T *result = malloc(sizeof(struct emxArray_real_T));

myFun(input arguments, result);

当我运行它时,我收到一条错误消息:分段错误。 gdb 给了我这个:

Program received signal SIGSEGV, Segmentation fault at:
99643: i0=retArray->size[0];

p retArray
$1 = (emxArray_real_T *) 0xc1d010

p retArray.size
$2 = (int32_T *) 0x0

p retArray.size[0]
Cannot access memora ar adress 0x0

我在我的主要功能中做错了吗?我希望如此,因为用 C 语言从 Matlab 翻译的代码是一团糟,或者可能只是对我这个新手而言。 如果我在没有返回值的情况下用 C 语言进行翻译和编译,代码可以正常工作。

【问题讨论】:

  • 这看起来 retArray 没有正确初始化,因为它的 size 成员指向 0 而不是分配的 int32_T。如果您可以向我们提供您的整个代码,这将有所帮助。 -- 编辑:不是你自己的代码,而是生成的 :p
  • 这可能很棘手,因为这个函数中有超过 100000 行。但是您认为使用 Matlab Coder 翻译的代码可能存在问题?
  • 我刚刚意识到我正在查看错误。
  • 评论中的这个基本上就是它了。只需多行几行即可读取用户输入并将其从命令行存储到变量,这些变量将传递给 myFun。
  • 您是否尝试从实际调用该函数的 matlab-code 生成代码?这大概会向您展示如何正确初始化数组。

标签: c++ c matlab struct


【解决方案1】:

你从 main 调用这个:

struct emxArray_real_T *result = malloc(sizeof(struct emxArray_real_T));

// result->size == 0;
// You would need to initialize this too.
// Somewhere in myFun it is accessed like this:
//   *retArray->size = x;
// or
//   x = *retArray->size;
// which causes the fault.

myFun(input arguments, result);

由于我对Matlab一无所知,因此我无法告诉您这是您必须做的事情,还是应该由生成的代码在某处完成。

您可以尝试这样修复它:

result->size = malloc(sizeof(int32_T));

【讨论】:

  • 不要转换malloc的结果。这将隐藏编译器错误。
  • 现在可以了,太好了。在调用 myFun 之前,我把 result->size=malloc(sizeof(int32_T)) @hhachem 指出这隐藏了编译器错误,所以这是应该小心还是我应该以其他方式这样做?再次感谢您回答 Qntm。
  • 不投malloc的返回值有多种原因。 1) 它是一个void*,它被隐式转换为任何其他指针类型。因此,额外的演员表是不必要的冗长,使阅读更加困难。 2) 如果您忘记包含&lt;stdlib.h&gt;,转换会隐藏编译器错误。有一堆关于这个问题的好文章here at SO.
  • 一般你当然应该检查malloc的返回值和0,因为这是指示分配错误的返回值。
猜你喜欢
  • 2014-06-09
  • 2019-05-05
  • 1970-01-01
  • 2019-04-04
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
相关资源
最近更新 更多