Создание массива переменного размера без malloc - PullRequest
0 голосов
/ 11 июня 2019

Я пишу программу на C, в которой я хочу прочитать длину массива и создать массив такого размера.Однако C не поддерживает массивы с переменной длиной, поэтому мне было интересно, как я могу это сделать.Я не хочу менять настройки моего компилятора.

Я думал о том, чтобы как-то использовать директиву препроцессора в свою пользу, но я не смог этого сделать.В значительной степени у меня есть целочисленная переменная, содержащая мой желаемый размер, и я хотел бы объявить массив с нулями.Кроме того, я не хочу использовать malloc / другие методы динамического массива.

Это может показаться базовым, но я пытался сделать это в течение некоторого времени.Если это имеет значение, я получаю размер массива через ввод / вывод.

Ответы [ 5 ]

2 голосов
/ 11 июня 2019

Существует несколько возможных решений, ни одно из которых не удовлетворяет всем вашим требованиям.

Вызов malloc является очевидным решением; вот для чего это. Вы сказали, что не хотите использовать malloc, но не объяснили почему.

C поддерживает массивы переменной длины - более или менее. VLA не существовали в C90, были введены в C99 и стали необязательными в C11. Поэтому, если вы хотите переносимый код, вы не можете предполагать, что он поддерживается. Если они есть, вы можете сделать что-то вроде этого:

int size;
// get value of size from input
int vla[size];

Есть некоторые ограничения. Если памяти недостаточно (размер стека может быть более строгим, чем размер кучи), поведение не определено. С другой стороны, то же самое верно для обычных массивов фиксированного размера, и VLA могут позволить вам выделять меньший объем памяти, чем предполагать фиксированную верхнюю границу. VLA существуют только в области видимости блока, поэтому объект перестает существовать, когда элемент управления покидает охватывающий блок (обычно, когда функция возвращается).

Вы можете определить массив (возможно, в области действия файла, вне определения любой функции), который, как вы знаете, достаточно велик для ваших данных. Вы должны будете указать некоторую верхнюю границу. Например, вы можете определить int arr[10000];, а затем отклонить любой ввод больше 10000. Затем вы можете использовать начальное подмножество этого массива для ваших данных.

Вы говорите, что хотите создать «массив переменного размера», но «вы не хотите использовать malloc / другие методы динамического массива». Похоже, вы хотите создать динамический массив, но вы не хотите создавать динамический массив. Это все равно что сказать, что ты хочешь привинтить винт, но не хочешь использовать отвертку.

0 голосов
/ 11 июня 2019

Любой язык, который поддерживает массивы переменной длины, использует механизм динамического выделения памяти для реализации функциональности. 'C' не имеет синтаксического сахара, который поддерживает истинные массивы переменной длины, но он предоставляет всю механику, необходимую для имитации.

malloc, realloc, free и другие могут легко использоваться для обработки динамических распределений и освобождений для массивов любого размера и типов элементов. Вы можете размещать данные в памяти и использовать указатель для возврата ссылки на функции вызывающей стороны или передачи другим функциям. (С другой стороны, VLA 'C' имеют ограниченное использование и не могут быть возвращены вызывающей стороне, если они размещены в стеке).

Итак, ваш лучший вариант (если вы не занимаетесь разработкой встроенного программного обеспечения) - начать использовать динамическое выделение памяти 'c'.

0 голосов
/ 11 июня 2019

Могу я спросить: почему у вас аллергия на malloc ()?

Причина, по которой я спрашиваю, состоит в том, что многие попытки определить безопасный профиль для C предполагают, что malloc является источникомвсе злоВ этом случае:

int *arr;
arr = mmap(0, sizeof *arr * N, PROT_READ|PROT_WRITE, MAP_PRIVATE, -1, 0);
0 голосов
/ 11 июня 2019

Что вы можете сделать, это прочитать длину массива, а затем сгенерировать исходный код программы:

fprintf(outfile, "int main(void) { static int arr[%d]; ...}\n", size);

Затем выполнить компилятор сгенерированной программы (например, с помощью функции system),и запустите получившийся исполняемый файл.

0 голосов
/ 11 июня 2019

Однако C не поддерживает массивы с переменной длиной,

Неправильно.Это совершенно правильный код C:

#include <stdio.h>

int main(void)
{
    int size;
    scanf("%d", &size);
    int arr[size];
}

Он называется VLA (массив переменной длины) и является частью C с 1999 года.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...