Как сделать динамический массив int - PullRequest
0 голосов
/ 06 мая 2019

У меня проблемы с настройкой динамического массива int. Я попробовал несколько примеров, но до сих пор не могу заставить его работать. Я думаю, что я делаю небольшую проблему с указателем, но я не могу понять, что. Я хочу иметь динамический массив int, а затем из другой функции добавить числа в этот массив. Я получил счетчик на работу.

Я пытался поставить * в разных местах и ​​пробовать свой путь, но на данный момент мне не хватает знаний, чтобы на самом деле знать, где должен быть *. Я знаю некоторые основы о & и *, но, видимо, недостаточно

static void counterFunction(int* pointerToArray[], int* count)
{
    while (*count < 10) {
        *(*pointerToArray + *count) = *count;
        *count = *count + 1;
    }
}

static int* writeSortedToArray(void)
{
    // I need to store 1000 numbers at this point
    int* dynamicArray = malloc(1000 * sizeof(int));
    int counter = 0;

    counterFunction(&dynamicArray, &counter);

    return 0;
}

Счетчик работает нормально, динамический массив не работает вообще. Он хранит только 0 согласно моему отладчику (xcode)

Ответы [ 4 ]

3 голосов
/ 06 мая 2019

Чтобы добавить к другим ответам, я бы предложил более общий подход и инкапсуляцию логики управления:

#include <assert.h>   // assert()
#include <stddef.h>   // size_t
#include <stdbool.h>  // bool, true, false
#include <stdlib.h>   // malloc(), calloc(), free(), EXIT_FAILURE, EXIT_SUCCESS
#include <stdio.h>    // fputs(), printf(), putchar()

typedef int value_type;
char const *conversion_specifier  = "%d"
size_t const initial_capacity     =  10
size_t growth_factor              =   2

typedef struct dynarray_tag {
    size_t size;
    size_t capacity;
    value_type *data;
} dynarray_t;

dynarray_t dynarray_create(void)
{
    dynarray_t new_dynarray = { 0, 0, NULL };
    return new_dynarray;
}

dynarray_t dynarray_create_reserve(size_t capacity)
{
    dynarray_t new_dynarray = { 0, capacity, NULL };
    new_dynarray.data = malloc(capacity * sizeof *new_dynarray.data);
    return new_dynarray;
}

dynarray_t dynarray_create_size(size_t size)
{
    dynarray_t new_dynarray = { size, size, NULL };
    new_dynarray.data = calloc(size, sizeof *new_dynarray.data);
    return new_dynarray;
}

bool dynarray_is_valid(dynarray_t const *dynarray)
{
    if (!dynarray)
        return false;

    if (!dynarray->size && !dynarray->capacity && !dynarray->data)
        return true;

    if (dynarray->size > dynarray->capacity)
        return false;

    if (dynarray->capacity && dynarray->data)
        return true;

    return false;
}

size_t dynarray_get_size(dynarray_t const *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray->size;
}

size_t dynarray_get_capacity(dynarray_t const *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray->capacity;
}

value_type* dynarray_at(dynarray_t *dynarray, size_t position)
{
    assert(dynarray_is_valid(dynarray) && dynarray->size && position < dynarray->size);
    return &dynarray->data[position];
}

value_type* dynarray_front(dynarray_t *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_at(dynarray, 0);
}

value_type* dynarray_back(dynarray_t *dynarray)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_at(dynarray, dynarray->size - 1);
}

bool dynarray_reserve(dynarray_t *dynarray, size_t new_capacity)
{
    assert(dynarray_is_valid(dynarray));

    if (new_capacity <= dynarray->capacity)
        return true;

    if (new_capacity < dynarray->size)
        return false;

    value_type *new_data = realloc(dynarray->data, new_capacity * sizeof *new_data);
    if (!new_data)
        return false;

    dynarray->data = new_data;
    dynarray->capacity = new_capacity;

    return true;
}

bool dynarray_resize(dynarray_t *dynarray, size_t new_size)
{
    assert(dynarray_is_valid(dynarray));

    if (new_size <= dynarray->capacity)
        return true;

    value_type *new_data = realloc(dynarray->data, new_size * sizeof *new_data);
    if (!new_data)
        return false;

    dynarray->data = new_data;
    dynarray->size = new_size;
    dynarray->capacity = new_size;

    return true;
}

bool dynarray_insert(dynarray_t *dynarray, size_t position, value_type value)
{
    assert(dynarray_is_valid(dynarray));

    if (dynarray->size + 1 > dynarray->capacity) {
        size_t new_capacity = dynarray->capacity ? dynarray->capacity * growth_factor : initial_capacity;
        if (!dynarray_reserve(dynarray, new_capacity))
            return false;
    }

    for (size_t i = dynarray->size; i > position; --i)
        dynarray->data[i] = dynarray->data[i - 1];

    dynarray->data[position] = value;
    dynarray->size++;

    return true;
}

bool dynarray_push_front(dynarray_t *dynarray, value_type value)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_insert(dynarray, 0, value);
}

bool dynarray_push_back(dynarray_t *dynarray, value_type value)
{
    assert(dynarray_is_valid(dynarray));
    return dynarray_insert(dynarray, dynarray->size, value);
}

bool dynarray_insert_sorted(dynarray_t *dynarray, value_type value)
{
    assert(dynarray_is_valid(dynarray));

    if (!dynarray_get_size(dynarray) || value < *dynarray_front(dynarray))
        return dynarray_push_front(dynarray, value);

    if (value > *dynarray_back(dynarray))
        return dynarray_push_back(dynarray, value);

    size_t insert_pos = 0;
    for (; insert_pos < dynarray->size && value > dynarray->data[insert_pos]; ++insert_pos);
    return dynarray_insert(dynarray, insert_pos, value);
}

void dynarray_print(dynarray_t const *dynarray)
{
    assert(dynarray_is_valid(dynarray));

    for (size_t i = 0; i < dynarray->size; ++i) {
        printf(conversion_specifier, dynarray->data[i]);
        if (i + 1 < dynarray->size)
            printf(", ");
    }
}

void dynarray_sort(dynarray_t *dynarray)  // insertion sort
{
    assert(dynarray_is_valid(dynarray));

    for (size_t i = 1; i < dynarray->size; i++) {
        value_type key = dynarray->data[i];

        size_t k = i - 1;
        for (; k >= 0 && dynarray->data[k] > key; --k)
            dynarray->data[k + 1] = dynarray->data[k];

        dynarray->data[k + 1] = key;
    }
}

void dynarray_free(dynarray_t *dynarray)
{
    assert(dynarray_is_valid(dynarray));

    free(dynarray->data);
    dynarray->size = dynarray->capacity = 0;
    dynarray->data = NULL;
}

int main(void)
{
    dynarray_t arr = dynarray_create();

    if (!dynarray_is_valid(&arr)) {
        fputs("Not enough memory. :(\n\n", stderr);
        return EXIT_FAILURE;
    }

    int result = EXIT_FAILURE;

    for (value_type i = 2; i < 15; i += 2) {
        if (!dynarray_push_back(&arr, i))
            goto error_exit;
    }
    dynarray_print(&arr);
    putchar('\n');

    for (value_type i = 1; i < 14; i += 2) {
        if (i != 7) {
            if (!dynarray_push_front(&arr, i))
                goto error_exit;            
        }
    }
    dynarray_print(&arr);
    putchar('\n');

    dynarray_sort(&arr);
    dynarray_print(&arr);
    putchar('\n');

    if (!dynarray_insert_sorted(&arr, 0))
        goto error_exit;
    dynarray_print(&arr);
    putchar('\n');

    if (!dynarray_insert_sorted(&arr, 15))
        goto error_exit;
    dynarray_print(&arr);
    putchar('\n');

    if (!dynarray_insert_sorted(&arr, 7))
        goto error_exit;
    dynarray_print(&arr);
    putchar('\n');

    result = EXIT_SUCCESS;

error_exit:
    result == EXIT_FAILURE && fputs("Not enough memory. :(\n\n", stderr);
    dynarray_free(&arr);
    return result;
}

Вывод:

2, 4, 6, 8, 10, 12, 14
13, 11, 9, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14
1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

Todo:

  • dynarray_insert_range()
  • dynarray_create_init() от пары итераторов
  • dynarray_from_file()
  • dynarray_copy()
  • dynarray_begin()
  • dynarray_end()
  • ...
0 голосов
/ 06 мая 2019

Вы делаете несколько ошибок:

1) int* pointerToArray[] - указатель на указатель (и). Вы должны использовать int* pointerToArray.

2) *(*pointerToArray+*count)=*count; разыменовывается pointerToArray два раза, вы должны использовать *(pointerToArray + *count) = *count;.

3) dynamicArray уже указатель, вы не должны использовать оператор & для получения его адреса. Тогда counterFunction(&dynamicArray, &counter); следует преобразовать в counterFunction(dynamicArray, &counter);.

Наконец, ваш код должен выглядеть так:

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

static void counterFunction(int * pointerToArray, int * count){

    while (*count < 10) {
        *(pointerToArray + *count) = *count;
        *count += 1;
    }
}


static int * writeSortedToArray(){

    //I need to store 1000 numbers at this point
    int * dynamicArray = malloc(100 * sizeof(int));
    int counter = 0;

    counterFunction(dynamicArray, &counter);

    // as suggested, finally release the array
    free(dynamicArray);

    return 0;
}

int main(){
    writeSortedToArray();
    return 0;
}
0 голосов
/ 06 мая 2019
static void counterFunction(int array[], int* count)
{
        ptrdiff_t i;

        for (i = *count; i < 10; i++)
                array[i] = i;
        *count = i;
}

static int *writeSortedToArray(void)
{
        //I need to store 1000 numbers at this point
        int *dynamicArray;
        int counter;

        dynamicArray = calloc(sizeof(*dynamicArray) * 1000);
        counter = 0;
        counterFunction(dynamicArray, &counter);
        /* counter == 10 */

        return dynamicArray;
}

Прежде всего, если функция всегда возвращает 0, она должна быть void (за исключением main() по своим собственным причинам).Хотя вы, вероятно, не хотите return 0, а вместо этого return массив.

Функция счетчика не должна знать, что массив является динамическим.Он может просто принимать любой массив и использовать его с нотацией массива.

Я перешел на цикл for, потому что он более естественный.

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

Я не понимаю цель вашегокод, но этот код - только исправленная версия вашего кода.

Не забывайте free(dynamicArray); в какой-то момент.

0 голосов
/ 06 мая 2019

Неправильное использование указателя здесь. Ваш Dynamicarray из WriteSortedToArray уже является адресом, поэтому вам не нужно передавать его как адрес. Это должно работать:

static void counterFunction(int* pointerToArray, int count){

while (count < 10)
{
    pointerToArray[count] = count;
    count++;
 }
}


static int* writeSortedToArray(void){

int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;

counterFunction(dynamicArray, counter);

return 0;
}

Если вы хотите сохранить значение вашего счетчика при выходе из CounterFunction, равное 10, сделайте это вместо:

static void counterFunction(int* pointerToArray, int *count){

while (*count < 10)
{
    pointerToArray[*count] = *count;
    *count++;
 }
}


static int* writeSortedToArray(void){

int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;

counterFunction(dynamicArray, &counter);

return 0;
}

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

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