Как переместить стек в кучу в Visual Studio 2019?

#c

#c

Вопрос:

Мне нужна помощь в устранении предупреждения в Visual Studio 2019.

Моя программа намеревается инициализировать с помощью нулей целочисленную матрицу размером 1000×1000 и получить входную строку вида «Включить с 12,45 по 56,78», или «Выключить с 12,45 по 56,78», или «Переключить с 12,45 по 56,78», где цифры представляют собой пару координат. Затем он печатает для отображения определенных частей входной строки, а именно. ВКЛ., ВЫКЛ., переключение и координаты.

Когда я выбираю опцию «Начать без отладки», результат получается не таким, как ожидалось, и я получаю предупреждение:

введите описание изображения здесь

Я прочитал документацию Microsoft по этой теме и следовал инструкциям в разделе «Для подавления предупреждения в IDE», но безрезультатно. Я задавал похожие вопросы в stackoverflow, но это тоже не помогло.

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define row_max 1000
#define column_max 1000

int instruction(char [], int, int, int, int);

int instruction(char light_status[],int row_start, int column_start, int row_end, int column_end)
{
    printf("Enter an instructionn");
    scanf_s("%s", light_status, 7);

    if (strcmp(light_status, "exit"))//strcmp results in 0 if the operands are equal
    {
        if (!strcmp(light_status, "toggle"))
            scanf_s("%d,%d %*s %d,%d", amp;row_start, amp;column_start, amp;row_end, amp;column_end);
        else
            scanf_s("%s %d,%d %*s %d,%d", light_status, 4, amp;row_start, amp;column_start, amp;row_end, amp;column_end);

        printf("Status %snrow_start %dncolumn_start %dnrow_end %dncolumn_end %dnn", light_status, row_start, column_start, row_end, column_end);
    }
    else
    {
        printf("The Endn");
        exit(0);
    }

    return 0;
}

int main()
{
    char light_status[7];
    int row, column, grid[row_max][column_max], row_start = 0, column_start = 0, row_end = 0, column_end = 0;

    //Initialising grid to 0
    for (row = 0; row < row_max; row  )
        for (column = 0; column < column_max; column  )
            *(*(grid   row)   column) = 0;

    while (1)
    {
        instruction(light_status, row_start, column_start, row_end, column_end);//extract important data from each instruction
    }

    return 0;
}
 

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

1. Пожалуйста, включите сообщения об ошибках / предупреждения в текст вашего сообщения, а не во внешнее изображение.

2. Если вы сделаете это static массивом, который будет в куче. Подавление предупреждения не вариант: массив слишком велик, чтобы безопасно находиться в стеке. Подавляйте предупреждения, только если вы действительно уверены , например, если вы используете стандарт scanf() , а не собственный MS scanf_s() , и не хотите, чтобы они вас раздражали.

3. относительно: char light_status[7]; и scanf_s("%s", light_status, 7); это недостаточно большой буфер для такой инструкции, как: Toggle 12,45 through 56,78 Пожалуйста, уточните, что вы на самом деле хотите сделать.

4. @user3629249 входные данные считываются до первого пробела и "Toggle" подходят, хотя совет не использовать небольшие массивы хорош.

5. что касается: *(*(grid row) column) = 0; Похоже, это не дает желаемого местоположения в «сетке», предложенной: *(*(grid row*column_max) column) = 0; Или намного лучше: grid[ row ][ column ] = 0;

Ответ №1:

grid Массив очень большой и занимает 4 000 000 байт, предполагая ( int 32 бита).

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

У вас есть в основном 4 варианта:

  • вы объявляете это static :
     static int grid[row_max][column_max];
     
  • вы перемещаете grid массив из main функции, чтобы он стал глобальной переменной.
  • как следует из предупреждения: вы перемещаете его в кучу, используя динамическое выделение памяти. Я бы не рекомендовал этого, потому что динамическое выделение 2D-массива несколько болезненно.
  • вы увеличиваете размер стека где-то в настройках проекта (я тоже этого не рекомендую).

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

1. но какие проблемы может вызвать стек размером 4 МБ? это все равно, что иметь приложение с 4 потоками. на самом деле это np

2. @АлексейНеудачин Я не уверен, понял ли я ваш комментарий. В Linux размер стека составляет 8 МБ, а в Windows — всего 1 МБ, если я правильно помню.

3. это по умолчанию

4. @АлексейНеудачин да, вы можете изменить размер стека, но ИМО это плохое решение. Что делать, если ваш массив занимает 100 МБ? Должны ли мы увеличить размер стека до 100 МБ?

5. это как simd против нескольких инструкций. здесь вы можете использовать simd

Ответ №2:

предлагаю: удалить это из main()

 grid[row_max][column_max],
 

и перед любым определением функции и после #define вставки s:

 int grid[row_max][column_max];
 

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

1. Не мой DV. Вероятно, из-за несуществующего объяснения.

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

Ответ №3:

просто увеличьте размер стека в настройках progect. стек намного быстрее, чем куча