如何制作动态int数组

时间:2019-05-06 08:41:34

标签: c arrays dynamic

我无法使我的动态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;
}

计数器正常工作,动态数组根本不工作。根据我的调试器(xcode),它只存储0

4 个答案:

答案 0 :(得分:3)

要添加其他答案,我建议采用更通用的方法和管理逻辑的封装:

#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()
  • ...

答案 1 :(得分:0)

您犯了一些错误:

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;
}

答案 2 :(得分:0)

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);

答案 3 :(得分:-1)

此处错误使用了指针。 WriteSortedToArray中的Dynamicarray已经是地址,因此您无需将其作为地址传递。 这应该可以工作:

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)