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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 17.12.2009, 15:20   #1
abr_question
Пользователь
 
Регистрация: 15.01.2008
Сообщений: 32
По умолчанию Управление динамическим массивом

Добрый день! Подскажите, что я делаю не так при управлении размером динамического массива? Язык - c

Код:
int *console;

void init_values()
{
console = (int*)malloc(0*sizeof(int));
console_p = 0;
}

void console_add(int button, int d)
{
	console = (int*)realloc(console, sizeof(console) + sizeof(int));
	console[console_p++] = button * d;
}
Пробовал процедуру переписать щё так:
Код:
	console = (int*)realloc(console, console_p++ + sizeof(int));
	console[console_p] = button * d;
Ошибка одна и та же - вылетает Segmentation fault.

Задумка вобще такая: я переписываю прогу с Delphi на C (Linux) и мне нужна альтернатива TStringList, в котором содержатся только числа.
В процедуре console_add задумка такая: для динамического массива console должно резервироваться памяти ровно на один дополнительный елемент (тип int) при каждом вызове процедуры. Ошибка вылетает после 6 вызовов.

Последний раз редактировалось abr_question; 17.12.2009 в 15:22.
abr_question вне форума Ответить с цитированием
Старый 17.12.2009, 16:18   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Ну вы же понимаете, что sizeof(console) == 4 байта на 32-х разрядных системах? Всегда. Мысль с console_p верна(если я правильно её понял, это ведь счётчик элементов?) но нужно домножать её на sizeof(int). А вообще так как вы делаете делать не хорошо, ибо медленно очень, увеличивайте размер массива сразу в два раза или как-то так. Отдельная переменная будет следить за размером массива, другая за кол-ством элементов в нём
netrino вне форума Ответить с цитированием
Старый 17.12.2009, 17:12   #3
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

Код:
console = (int*)realloc(console, sizeof(console) + sizeof(int));
как заметили выше сизеоф тут не подходит, зато подходит _msize(console) который вернет как раз размер всего блока памяти
m0nax вне форума Ответить с цитированием
Старый 17.12.2009, 17:31   #4
abr_question
Пользователь
 
Регистрация: 15.01.2008
Сообщений: 32
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
Ну вы же понимаете, что sizeof(console) == 4 байта на 32-х разрядных системах? Всегда. Мысль с console_p верна(если я правильно её понял, это ведь счётчик элементов?) но нужно домножать её на sizeof(int). А вообще так как вы делаете делать не хорошо, ибо медленно очень, увеличивайте размер массива сразу в два раза или как-то так. Отдельная переменная будет следить за размером массива, другая за кол-ством элементов в нём
Точно! Неверно второй пример указал. Счас переделал:
Код:
void console_add(int button, int d)
{
	console = (int*)realloc(console, ++console_p * sizeof(int));
	console[console_p]= button * d;
}
Тем не менее, зависимость остаётся прежней - 6 раз вызовов и Segmentation fault.
Счас попробую с увеличением массива в 2 раза.

Цитата:
Сообщение от m0nax Посмотреть сообщение
Код:
console = (int*)realloc(console, sizeof(console) + sizeof(int));
как заметили выше сизеоф тут не подходит, зато подходит _msize(console) который вернет как раз размер всего блока памяти
Проблемка с _msize. Справочники указыают, что она хранится в malloc.h, но у меня malloc.h не содержит такой функции. Более того, весь /usr/include не содержит ни одного файла, в которой данная функция присутствует. Она не устарела случаем?
abr_question вне форума Ответить с цитированием
Старый 17.12.2009, 17:40   #5
abr_question
Пользователь
 
Регистрация: 15.01.2008
Сообщений: 32
Счастье

Ааааагрх! Всё! Нашёл, кажется, ошибку
Я же инициализирую console_p = 0. Размер тоже правильно устанавливаю, как ++console_p * sizeof(int). А затем делаю глупейшую ошибку и присваиваю значение по адресу console_p, который уже за массивом.
Счас переписал
Код:
void init_values()
{
	console_p = -1;
	console = (int*)malloc(0*sizeof(int));
}
void console_add(int button, int d)
{
	console = (int*)realloc(console, (++console_p + 1) * sizeof(int));
	console[console_p]= button * d;
}
Вроде не вылетает при вызове приличное количество раз. Но если что, я щё отпишусь..
Спасибо всем, кто помог
abr_question вне форума Ответить с цитированием
Старый 17.12.2009, 17:43   #6
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Код:
int* console = 0;
unsigned int console_p = 0;
unsigned int list_size = 0;

void init_values()
{
    list_size = 10*sizeof(int);
    console = malloc(list_size);

    return;
}

void console_add(int button, int d)
{
    if( (console_p+1)*sizeof(int) >= list_size ) {
        list_size <<= 1; // lise_size *= 2;
        console = (int*)realloc(console, list_size);
    }
    console[console_p++] = button * d;

    return;
}
Как-то так должно выглядеть ) Проверьте - если опять будет ошибка, то возможно она в другом месте

Последний раз редактировалось netrino; 17.12.2009 в 18:29. Причина: поправил
netrino вне форума Ответить с цитированием
Старый 17.12.2009, 19:28   #7
abr_question
Пользователь
 
Регистрация: 15.01.2008
Сообщений: 32
По умолчанию

netrino, спасибо! Возьму вариант на заметку, если полетит ныне существующий.

У меня щё есть один вопрос, но он уже по указателям.
Хочу сделать так, чтобы в функция обрабатывала не один массив, а несколько. То есть, возникла необходимость функцию привести к общему виду. Фактически получилось так:

Код:
array_add(&console, &console_p, data);

void array_add(int **arr, int *arr_p, int d)
{
	*arr = (int*)realloc(*arr, (++(*arr_p) + 1) * sizeof(int));
	*arr[*arr_p] = d;
}
С arr_p проблем вобще не возникло - по указателю увеличивает на единицу. А вот с массивом не получается, хоть убейся. realloc не хочет никак увеличивать размерность массива. Поетому вторая строка функции выдаёт ошибку. Пробовал заменять int **arr на *arr[] - результат тот же.. Что делать?
abr_question вне форума Ответить с цитированием
Старый 17.12.2009, 19:40   #8
RoS
Форумчанин
 
Аватар для RoS
 
Регистрация: 13.12.2009
Сообщений: 272
По умолчанию

Цитата:
Сообщение от abr_question Посмотреть сообщение
netrino, спасибо! Возьму вариант на заметку, если полетит ныне существующий.

У меня щё есть один вопрос, но он уже по указателям.
Хочу сделать так, чтобы в функция обрабатывала не один массив, а несколько. То есть, возникла необходимость функцию привести к общему виду. Фактически получилось так:

Код:
array_add(&console, &console_p, data);

void array_add(int **arr, int *arr_p, int d)
{
	*arr = (int*)realloc(*arr, (++(*arr_p) + 1) * sizeof(int));
	*arr[*arr_p] = d;
}
С arr_p проблем вобще не возникло - по указателю увеличивает на единицу. А вот с массивом не получается, хоть убейся. realloc не хочет никак увеличивать размерность массива. Поетому вторая строка функции выдаёт ошибку. Пробовал заменять int **arr на *arr[] - результат тот же.. Что делать?
Кажется, у тебя был одномерный массив? т.е. и функция принимать должна int*, либо int array[]...
Если я помог вам - порадуйте меня, нажмите на весы слева
RoS вне форума Ответить с цитированием
Старый 17.12.2009, 20:09   #9
abr_question
Пользователь
 
Регистрация: 15.01.2008
Сообщений: 32
По умолчанию

RoS, имеется ввиду ето?:
Код:
array_add(console, &console_p, data);

void array_add(int arr[], int *arr_p, int d)
{
	arr = (int*)realloc(arr, (++(*arr_p) + 1) * sizeof(int));
	arr[*arr_p] = d;
}
В етой функции до и после первой строчки размер arr = 4. То есть, не увеличивается...
abr_question вне форума Ответить с цитированием
Старый 17.12.2009, 21:52   #10
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

С двойным указателем там верно было.. Насчёт
Код:
*arr[*arr_p] = d;
Тут нужно так:
Код:
(*arr)[*arr_p] = d;
а вообще я бы советовал завести отдельную структуру, в которой бы содержался как минимум указатель на память и счётчик объектов, так будет удобней
netrino вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с динамическим массивом TheKnyazz Общие вопросы C/C++ 3 28.04.2009 18:37
Проблемма с динамическим массивом Arassir Помощь студентам 3 15.02.2009 12:37
Помогите с динамическим массивом!!!! vish25 Помощь студентам 2 31.05.2008 19:20
проблема с динамическим массивом romeo007.06 Общие вопросы Delphi 1 03.04.2008 20:18
проблема с динамическим массивом kommunist Помощь студентам 6 11.11.2007 21:18