Переполнение или ошибка памяти c

#c #arrays

#c #массивы

Вопрос:

Это можно считать вопросом домашнего задания. Эта проблема хорошо известна: «у вас есть треугольник чисел, и вы должны найти наибольшую сумму«

ну, нет проблем, я некоторое время назад создал решение на python, работает безупречно. Но теперь в c решением является 75256, мой ответ — 9729. Итак, проблема в том, что тип short переполняется.

Итак, чтобы исправить это, я предположил, что изменение моего массива на тип int решит все.. но затем, при объявлении массива a[1001][1001] он зависает (я думаю, ошибка памяти).

кто-нибудь знает, что делать? Я пробовал что-то с другим значением int, и всякий раз, когда значение в a становилось больше 32767, оно увеличивалось, но мое решение по-прежнему отклонялось от 300? (код работает — протестирован на многих небольших массивах)

 #include <iostream>
#include <fstream>

int main() {
    std::ofstream fout ("numtri.out");
    std::ifstream fin  ("numtri.in");
    short trifield[1001][1001] = {0};
    int Rows, tmp=0;
    fin >> Rows;
    for (int x = 0; x<Rows;x  ) 
        for (int nr = 0; nr<=x;nr  ){
            fin >> tmp;
            trifield[x][nr] = tmp;}

    for (int y = (Rows-2); y > -1; y--)
        for (int x = 0; x <= y 1; x  ) {
            int a = trifield[y 1][x];
            int b = trifield[y 1][x 1];
            if (a > b) trifield[y][x]  = a;
            else       trifield[y][x]  = b;
        }
    fout << trifield[0][0] << std::endl;
    return 0;    
}
  

примечание: Я не ищу решение, просто хороший способ справиться с переполнениями, примеры приветствуются!

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

1. Ваш массив по-прежнему определен как короткий…

2. да, int приведет к ошибке

3. Вы проверили в отладчике, что делает программа, когда она попадает в массив, и массив определен как имеющий тип int?

Ответ №1:

Если у вас возникли проблемы с памятью, попробуйте назначить свой массив динамически:

 short** trifield = new short[1001][1001];
  

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

1. Не могли бы вы, пожалуйста, объяснить немного больше?

2. @Buster если вы выделяете память напрямую, это делается в пространстве стека. Это пространство обычно довольно ограничено. Вместо динамического распределения вы можете получить доступ к гораздо большему объему памяти.

3. И у вас также будет намного больше памяти, если вы переместите массив за пределы main. Здесь нет необходимости в динамическом распределении, поскольку существует только один массив и его размер известен.

Ответ №2:

У вас есть массив из 1001×1001 коротких строк… это 1002001 * 2 байта. Все это происходит в вашем локальном стеке. В зависимости от вашей системы это может быть СЛИШКОМ большим. Попробуйте вместо этого выделить пространство для вашего ‘trifield’ с помощью malloc. Посмотрите, что это дает для вас

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

1. и помни, какие у тебя mallocs, ты должен освободить

2. И поскольку вопрос касается C , в любом случае не используйте malloc.

Ответ №3:

Вы получаете переполнение стека вместо числового переполнения!

Переместите массив в статическую память за пределами main, чтобы он не использовал стек.

Ответ №4:

Способ, которым я проверяю переполнение, заключается в проверке явно поддельного результата. Например,

 if (myInt   1 < myInt) {
    // Overflow condition
    cerr << "Overflow" << endl;
}
else {
    myInt  ;
}
  

Ответ №5:

Переполнение int — это UB. Переполнение беззнакового значения int определено в стандарте.

Итак, единственный способ — вручную проверить значения перед выполнением операции и убедиться, что они не переполняются.