есть ли предупреждение компилятора для этого?

#c #memory-management #stdvector

#c #управление памятью #stdvector

Вопрос:

Рассмотрим следующий фрагмент кода:

     curve amp;c = cuts[p.first];
    sort(p.second.begin(),p.second.end(),[amp;](Point p1, Point p2) {
        return c.ordered(p1,p2);
      });
    if (norm(Point(c.first()) - p.second[0]) > 1)
      cuts.push_back(c.subcurve(c.first(),p.second[0]));
    for (unsigned i = 1 ; i   2 < p.second.size() ; i  = 2)
      cuts.push_back(c.subcurve(p.second[i],p.second[i   1]));
    if (norm(Point(c.last()) - p.second.back()) > 1)
      c = c.subcurve(p.second.back(),c.last());
 

Это небольшой фрагмент кода OpenCV, и важно то, что cuts — это вектор кривых, а p.first — это индекс в этом векторе. Чтобы сделать код более читаемым, я cuts[p.first] заменил его просто c потому, что он часто используется в теле.

Этот код содержит ошибки, и это ошибка, с которой я сталкивался не раз. Проблема (возможно, вы захотите сначала просмотреть код и посмотреть, сможете ли вы его найти) заключается в том, что нажатие нового элемента на cuts может сделать недействительным указатель, который есть c .

Ошибки, подобные этому, должны быть, по крайней мере, смутно распространенными (то, что я делаю, чтобы сделать код более читаемым, разумно), но их трудно отследить, особенно если происходит рандомизация или многопоточность, потому что точка, в которой происходит перераспределение вектора, может меняться от запуска к запуску. Но это должно быть очевидно для компилятора, поскольку вы используете указатель на блок памяти, который может быть перераспределен. И это мой вопрос: есть ли какой-либо способ заставить компилятор предупреждать вас, когда вы совершаете эту ошибку?

Спасибо!

Комментарии:

1. Это задание для проверки кода. Это способ заставить компилятор разобраться. Код, который выполняет перераспределение, может даже не находиться в той же единице перевода, что и этот код, и если это так, то у компилятора нет даже шанса.

2. Я не эксперт по компилятору, но я сомневаюсь, что компилятор не может легко, если вообще может, обнаружить подобные ошибки.

3. Возможно, вы захотите попробовать статические анализаторы, хотя я не уверен, помогут ли они в этом случае.

4. Но это должно быть очевидно для компилятора, поскольку вы используете указатель на блок памяти, который может быть перераспределен. Здесь вы говорите о динамической памяти. Компилятору нелегко это обнаружить.

5. Я предлагаю полагаться на включение предупреждений вашего компилятора и использование дезинфицирующих средств, чтобы помочь выявить ошибки такого рода. Ответственность за корректность программы в C лежит на программисте. В качестве альтернативы, существует множество языков программирования, которые подчеркивают безопасность и корректность, так что программист не может совершать подобные ошибки (если только функции безопасности языка явно не отключены).