Получение неправильного количества элементов в динамическом массиве - PullRequest
0 голосов
/ 27 февраля 2019

Я новичок в C и пытаюсь создать очень простой динамический массив.Мой код компилируется, но выводит неправильный размер при возврате размера массива.Например, когда я проверяю его на окончательный размер массива 0, он выдает 13744632839234567870, который очень большой и очень неправильный.

Я не думаю, что моя функция array_size неверна.Я подозреваю, что это не так в append, но я просто не могу найти, что с ним не так.

Если кто-нибудь захочет мне помочь, я буду очень признателен!

#include <stdlib.h>

struct array
{
    long size;
    long capacity;
    int* data;
};

struct array* array_init(long initial_capacity) {
    struct array* v = malloc(sizeof(struct array)); 
    if (v==NULL){
        return NULL;
    }
}    

int append(struct array *v, int elem) {
    if (v->size >= v->capacity) {

        v->capacity *= 2;
        v->data = realloc(v->data, sizeof(int) * v->capacity);
    }
    v->data[v->size] = elem;
    v->size++;
    return 0;    
}

int indexget(struct array *v, long index) {
    if (index >= v->size) {
        return NULL;
    }
    return v->data[index];
}

long array_size(struct array *v) {
    return v->size;
}

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

внутри array_init вы должны установить size и capacity на 0, иначе они будут иметь случайные значения.

также внутри append, после realloc вам нужно проверить NULL.

0 голосов
/ 27 февраля 2019

array_init() не назначил ничего для .size и .capacity членов.

Предлагаемые изменения:

struct array {
    // long size;
    // long capacity;
    // `size_t` is the right-size for array indexing.
    // Be mindful that `size_t` is some _unsigned_ type.
    size_t size;
    size_t capacity;
    int* data;
};

// struct array* array_init(long initial_capacity) {
struct array* array_init(size_t initial_capacity) {
    struct array* v = malloc(sizeof(struct array)); 
    if (v == NULL) {
       return NULL;
    }
    v->data = malloc(sizeof(int)*initial_capacity );
    // If initial_capacity is 0, a NULL return does not certainly mean out of memory
    //if (v->data==NULL){
    if (v->data==NULL && initial_capacity != 0){
       free(v); // also free prior allocation
       return NULL;
    }

    // Add
    v->size = 0;
    v->capacity = initial_capacity;

    return v;
}    

v->capacity *= 2 слабое, поскольку это не такИзвестно, что v->capacity > 0.

int append(struct array *v, int elem) {
    if (v->size >= v->capacity) {
        // v->capacity *= 2;
        v->capacity = v->capacity > 0 ? v->capacity*2 : 1;

indexget() неясно.Зачем возвращать указатель , когда индекс выходит за пределы диапазона?

#define BAD_VALUE 0  /* or some unused `int` value for the application */
int indexget(struct array *v, long index) {
    // if (index >= v->size) {  incomplete test if `index` is signed
    if (index >= v->size || index < 0) {
        // return NULL;
        return BAD_VALUE;
    }
    return v->data[index];
}

или

Код возвращает адрес элемента массива?

//int indexget(struct array *v, long index) {
int *indexget(struct array *v, size_t index) {
    if (index >= v->size) {
        return NULL;
    }
    // return v->data[index];
    return &v->data[index];
}

append() отсутствуетпроверка успешности перераспределения.

        // v->data = realloc(v->data, sizeof(int) * v->capacity);
        void *p = realloc(v->data, sizeof(int) * v->capacity);
        if (p == NULL) {
          return EXIT_FAILURE; // Handle out-of-memory in some fashion
        }
        v->data = p;
...