-1

the toolchain I use is Clion MinGW Bundle
the original code was generated by matlab
Why SIGTRAP occured when tried to allocate memory?

#define CODER_NEW(T, N) new T[N]
void reserve(SZ _n) {
  if (_n > capacity_) {
    T* const new_data{CODER_NEW(T, _n)}; //problem occur
    (void)std::copy(data_, data_ + size_, new_data);
    if (owner_) {
      CODER_DELETE(data_);
    }
    data_ = new_data;
    capacity_ = _n;
    owner_ = true;
  }
}

enter image description here enter image description here

anatolyg
  • 26,506
  • 9
  • 60
  • 134
desperateLord
  • 303
  • 2
  • 9
  • 1
    My guess would be somewhere else in your program corrupted the heap, please show a [mre] – Alan Birtles Feb 22 '22 at 08:11
  • Does "the original code was generated by matlab" mean that you have been tinkering with generated code? – molbdnilo Feb 22 '22 at 08:24
  • @molbdnilo I know why now. Original matlab code can automatic increase capacity. But C++ code doesn't. It writes data without examing. Matlab Coder is buggy. I wish they can fix this. – desperateLord Feb 22 '22 at 09:58

1 Answers1

1

Here is a simple matlab function

function [array] = test(num)
    array = 1:num;
    for i = 1:10 * num
        array(i) = sqrt(double(i)) * num;
    end
end

It dynamically increase the size of array. I write this code so that coder cannot guess what size of array will return. Then I use coder to generate C++ code and use following code to call test(int num, coder::array<int, 2U> &array). Guess what, It crashed.

auto array = new coder::array<int, 2U>();
test(100, *array);
delete array;

Let's see what happened inside this function.

void test(int num, coder::array<int, 2U> &array)
{
  double d;
  long long i;
  int i1;
  // 'test:2' array = 1:num;
  coder::eml_integer_colon_dispatcher(num, array);
  // 'test:3' for i = 1:10 * num
  i = 10LL * num;
  if (i > 2147483647LL) {
    i = 2147483647LL;
  } else if (i < -2147483648LL) {
    i = -2147483648LL;
  }
  i1 = static_cast<int>(i);
  for (int b_i = 0; b_i < i1; b_i++) {
    int i2;
    // 'test:4' array(i) = sqrt(double(i)) * num;
    d = b_i + 1;
    coder::b_sqrt(&d);
    d = rt_roundd_snf(d * static_cast<double>(num));
    if (d < 2.147483648E+9) {
      if (d >= -2.147483648E+9) {
        i2 = static_cast<int>(d);
      } else {
        i2 = MIN_int32_T;
      }
    } else if (d >= 2.147483648E+9) {
      i2 = MAX_int32_T;
    } else {
      i2 = 0;
    }
    array[b_i] = i2;
  }
}

First, it allocate memory is size of num. Then it write data to array. The problem here is that it didn't really check index outbound or not. The real problem here is that array coder produce unlike stl vector is not memory safe. Coder does not write data before check memory outbound.

desperateLord
  • 303
  • 2
  • 9
  • Why do you create the array (especially with size 2??) on the heap? That seems like a massive [nonbo](https://www.urbandictionary.com/define.php?term=nonbo). Also the code has so many magic numbers, it's impossible to tell what it does. You might want to consider using [std::numeric_limits](https://en.cppreference.com/w/cpp/types/numeric_limits) – infinitezero Feb 22 '22 at 10:56
  • `Why do you create the array (especially with size 2??` The array has two _dimensions_. `coder::` is not `std::`. `Also the code has so many magic number` yes, it was _autogenerated_ by matlab-coder. – KamilCuk Feb 22 '22 at 11:06
  • @infinitezero It's generated by matlab coder. I wish it better too. – desperateLord Feb 22 '22 at 11:13