Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.07.2021, 22:46   #1
Roberttt
Пользователь
 
Регистрация: 30.05.2018
Сообщений: 56
По умолчанию Структуры для заполнения динамического массива в СИ

Здравствуйте! Написал код для заполнения двумерного динамического массива, но при подстановке значений 1 и 0 (одна строка и ноль элементов в этой строке) компилятор выдает ошибку "Segmentation fault". Я думаю ошибка в функции array_array_int_min, потому что там нету проверки для нулевого количества элементов массива, но я попробовал добавить еще один if, а в итоге даже второй тест не прошел. Можете, пожалуйста, подсказать дело в функции array_array_int_min или нет?

Код:
/* Вы можете пользоваться этими функциями из предыдущих заданий */
size_t read_size() { size_t i; scanf("%zu", &i); return i; }

void array_int_fill( int64_t* array, size_t sz );

struct array_int array_int_read();
struct maybe_int64 array_int_get( struct array_int a, size_t i );
bool array_int_set( struct array_int a, size_t i, int64_t value );
void array_int_print( struct array_int array );
struct maybe_int64 array_int_min( struct array_int array );
void array_int_free( struct array_int a );

void array_int_normalize( struct array_int array, int64_t m ) {
  for (size_t i = 0; i < array.size; i = i + 1) {
    array.data[i] = array.data[i] - m;
  }
}

/* --- int[] --- */

struct maybe_array_int {
    struct array_int value;
    bool valid;
};

struct maybe_int64{
    int64_t value;
    bool valid;
};


/* --- int[][] --- */

struct array_array_int{
    struct array_int* data;
    size_t size;
};

struct array_int {
    int64_t* data;
    size_t size;
};


/* --- rows --- */

struct maybe_array_int array_array_int_get_row( struct array_array_int a, size_t i ) {
  if ( 0 <= i && i < a.size ) { return (struct maybe_array_int) { array, true }; }
  else { return (struct maybe_array_int) { {NULL, 0}, false; };
}

bool array_array_int_set_row( struct array_array_int a, size_t i, struct array_int value ) {
  if (0 <= i && i < a.size) {
    a.data[i] = value;
    return true;
  }
  else { return false; }
}


/* --- get/set --- */

struct maybe_int64 array_array_int_get( struct array_array_int a, size_t i, size_t j ) {
    if ( i < a.size ) {
        if ( j < a.data[i].size ) {
            return (struct maybe_int64) {.value = a.data[i].data[i], .valid = true };
        }
        else return (struct maybe_int64) {0};
    }
    else return (struct maybe_int64) {0};
}

bool array_array_int_set( struct array_array_int a, size_t i, size_t j, int64_t value ) {
    if ( i < a.size ) {
        if ( j < a.data[i].size ) {
            a.data[i].data[j] = value;
            return true;
        }
        else return false;
    }
    else return false;
}


/* --- read/print */

struct array_array_int array_array_int_read() {
    const size_t rows = read_size();
    if ( rows > 0) {
        struct array_int* marray = malloc( rows * sizeof( struct array_int ));

        for( size_t i = 0; i < rows; i++ ) {
            marray[i] = array_int_read();
        }
        return (struct array_array_int) { .data = marray, . size = rows };
    }
    else return (struct array_array_int) { .data = NULL, .size = 0 };
}

void array_array_int_print( struct array_array_int array ) {
    for( size_t i = 0; i < array.size; i++ ) {
        array_int_print( array.data[i] );
        printf("\n");
    }
}


/* ---- min/normalize */

struct maybe_int64 array_array_int_min( struct array_array_int array ) {
    int64_t min = array.data[0].data[0];

    if ( array.size > 0 ) {
        for ( size_t i = 0; i < array.size; i++ ) {
            for( size_t j = 0; j < array.data[i].size ; j++ ) {
                if ( array.data[i].data[j] < min ) {
                    min = array.data[i].data[j];
                }
                continue;
            }
        }
        return (struct maybe_int64) {.value = min, .valid = true};
    }
    else return (struct maybe_int64) {0};
}

void array_array_int_normalize( struct array_array_int array, int64_t m) {
  for (size_t i = 0; i < array.size; i = i + 1) {
    const struct maybe_array_int cur_row = array_array_int_get_row( array, i );
    if (cur_row.valid) {
         array_int_normalize( cur_row.value, m );
    }
  }
}

void array_array_int_free( struct array_array_int array ) {
    if ( array.size > 0 ) {
        for( size_t i = 0; i < array.size; i++ ) {
            free(array.data[i].data);
        }
        free(array.data);
    }
}
Roberttt вне форума Ответить с цитированием
Старый 22.07.2021, 00:32   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

По порядку. "array_int_normalize" для краткости кода можно записать:
Код:
for (size_t i = 0; i < array.size; i++) {
    array.data[i] -= m;
}
"array_array_int_get_row" - i можно не проверять на ноль, так как тип size_t беззнаковый. "array_array_int_set_row" - аналогично i на ноль не проверять; если data[i] хранил ненулевой указатель, то произойдет утечка памяти. "array_array_int_get" - опечатка в индексах при получении значения (два раза i), можно вместо двух if просто объединить условия через логическое И. "array_array_int_set" - аналогично объединить условия. "array_array_int_min" - разыменование нулевого указателя вызывает Segmentation fault; например, можно написать так:
Код:
struct maybe_int64 array_array_int_min( struct array_array_int array ) {
    int64_t min = 0;
    bool valid = false;

    for ( size_t i = 0; i < array.size; i++ ) {
        for( size_t j = 0; j < array.data[i].size; j++ ) {
            if ( !valid || array.data[i].data[j] < min ) {
                min = array.data[i].data[j];
                valid = true;
            }
        }
    }

    return (struct maybe_int64) {.value = min, .valid = valid};
}
"array_array_int_free" - можно не проверять array.size.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 22.07.2021, 01:22   #3
Roberttt
Пользователь
 
Регистрация: 30.05.2018
Сообщений: 56
По умолчанию

Огромное Вам спасибо! Я целый день возился с функцией "array_array_int_min", не понимая, что в ней неправильно. Вы очень сильно мне помогаете!
Roberttt вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Структуры для заполнения динамического массива в СИ Roberttt Помощь студентам 5 20.07.2021 23:00
Функция заполнения динамического массива Joose Общие вопросы C/C++ 5 05.03.2013 23:25
Функция заполнения динамического массива случайными числами Beren42 Помощь студентам 3 16.10.2012 10:40
метод класса для заполнения массива Assemblerru Общие вопросы C/C++ 3 23.03.2011 04:09
Переделать для динамического массива. Ueshua Общие вопросы C/C++ 1 20.12.2009 21:33