Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 29.11.2015
Сообщений: 19

Перевыделение памяти realloc

07.03.2016, 15:56. Показов 3648. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть двумерный массив char **inpWords, в который я добавляю слова из файла, отсеивая пробельные символы. из файла считываю посимвольно. Перед добавлением в массив проверяю, если памяти не хватает, то расширяю ее с помощью realloc. Как я понимаю, в 25 строке не происходит увеличение памяти. Как следствие, в 19 строке при countWord=2 вылетает ошибка, т.к. происходит обращение к неразмеченной области памяти (Ошибка: EXC_BAD_ACCESS (code=1, adress=0x33). Что я делаю не так?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    unsigned N=25;//Предполагаемое начальное число символов в слове
    unsigned M=2;//Число ожидаемых слов во всех файлах (кол-во строк в массиве)
    unsigned countWord=0;//число считанных слов из файла, инкриментируется в процессе считывания
    unsigned index=0;
 
    char **inpWords=(char**)malloc(M*sizeof(char*));
    for (int i=0;i<M;i++){
        inpWords[i]=(char*)malloc(N*sizeof(char));
    }
 
        char ch=getc(f);
        while(ch != EOF){
            if(!isspace(ch) && !ispunct(ch)){
                //Выделение дополнительной памяти, если число символов в слове больше, чем было выделено изначально
                if (index>=N){
                    N+=15;
                    inpWords[countWord] = (char*)realloc(inpWords[countWord], N*sizeof(char));//увеличиваем размер памяти под слово на 15 символов
                }
                inpWords[countWord][index]=ch;
                index++;
            }
            else{
                if (countWord>=M){
                    M+=15;
                    inpWords=(char**)realloc(inpWords, M*sizeof(char*));//если число слов больше, чем было выделено памяти изначально, то добавляем память еще под 15 указателей на массивы char*
                }
                if (index){
                    inpWords[countWord++][index]='\0';
                    printf("%s\n",inpWords[countWord-1]);
                    index=0;
                }
            }
            ch=getc(f);
        }
Добавлено через 16 минут
Только что доперло: проблема, видимо в том, что я создал указатели на массивы char*, а под сами массивы память не выделил.

Тогда попутно вопрос такой:

если есть массив char* mas, необходимо выполнить для него операцию free(mas). Можно передать указатель на массив в функцию и там освободить память?

C
1
2
void freeMem(char * array)
    free(array);
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.03.2016, 15:56
Ответы с готовыми решениями:

Перераспределение памяти, realloc
Есть код, который считывает из файла слова и записывает их в динамическую записную книжку. Всё работает сначала нормально. Ошибка возникает...

Ошибка при перераспределении памяти realloc
Здравствуйте, дорогие друзья. Помогите, пожалуйста разобраться с перераспределением памяти для динамических массивов. Задача: В...

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

5
 Аватар для yrceus
88 / 88 / 80
Регистрация: 25.08.2013
Сообщений: 337
07.03.2016, 16:53
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
 
int main() {
    unsigned N = 25;
    unsigned M = 2;
    unsigned countWord = 0;
    unsigned index = 0;
 
    char **inpWords = (char**)malloc(M * sizeof(char*));
    for (int i = 0; i < M; i++) {
        inpWords[i] = (char*)malloc(N * sizeof(char));
    }
 
    char ch = getc(stdin); // читает из потока ввода
    while (ch != EOF) {
        if (!isspace(ch) && !ispunct(ch)) {
            
            if (index >= N) {
                N += 15;
                inpWords[countWord] = (char*)realloc(inpWords[countWord], N * sizeof(char));
            }
            inpWords[countWord][index++] = ch; // поставил сюда постф. инкр.
        }
        else {
            if (index) { // этот иф был внизу
                inpWords[countWord++][index] = '\0';
                printf("%s %d\n", inpWords[countWord - 1], countWord - 1);
                index = 0;
            }
            if (countWord == M - 1) { // изменил условие и поменял ифы местами
                M += 15;
                inpWords = (char**)realloc(inpWords, M * sizeof(char*));
                for (int i = 0; i < M; i++) {
                    inpWords[i] = (char*)malloc(N * sizeof(char)); // добавил выделение памяти
                }
            }
        }
        ch = getc(stdin);
    }
    free(inpWords);
    return 0;
}
Добавлено через 3 минуты
Вы не выделяли память под сами слова, после двух введенных слов.

Добавлено через 23 минуты
C
1
2
3
void freeMem(char *arr) {
    free(arr);
}
Думаю можно
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13202 / 6837 / 1822
Регистрация: 18.10.2014
Сообщений: 17,296
07.03.2016, 18:08
Программа содержит еще одну классическую ошибку: результат 'getc ()' кладется в переменую типа 'char'. А надо бы 'int'.
1
 Аватар для yrceus
88 / 88 / 80
Регистрация: 25.08.2013
Сообщений: 337
07.03.2016, 19:23
А как тогда? Тогда, чтобы исключить приведение типов, **inpWords тоже необходимо так же определять типа int.
И потом придется в цикле посимвольно печатать.
А чем чревато передавать результат getc() в переменную типа char?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13202 / 6837 / 1822
Регистрация: 18.10.2014
Сообщений: 17,296
07.03.2016, 19:53
Значение EOF, которое может возвращать функция getc(), в общем случае не принадлежит диапазону типа 'char'. Это "допонительное" значение. Поэтому результат getc() надо принимать в переменную типа 'int', проверять на равенство с EOF, и только после этого рассматривать, как 'char'. (После этого гарантируется, что возвращенное значение поместится в 'char'). Если ваша программа работает, то вам "повезло", но формально ваша программа некорректна именно по этой причине.

Исключать "приведение типа" и переобъявлять ваши массивы как 'int', разумеется, не надо? Зачем? Ничего вообще больше в коде менять не надо. Значение типа 'int' само преобразуется к типу 'char' при сохранении в массив. Вам об этом беспокоиться не нужно.
1
 Аватар для yrceus
88 / 88 / 80
Регистрация: 25.08.2013
Сообщений: 337
07.03.2016, 19:56
Ага, понял) Спасибо) Вспомнил, читал об этом, да))))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.03.2016, 19:56
Помогаю со студенческими работами здесь

Работа с кучей. Перевыделение памяти
Для объяснения вопроса приведу сначала пример: #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; class Man { private: char* Name; ...

Перевыделение памяти в функции - динамический массив
Доброе время суток, Подскажите как сделать такую задачу Только перешел на динамические массивы За ранее благодарен Описать массив...

Динамические массивы структур и выделение (перевыделение) памяти
Здравствуйте. Делаю систему обновления. С ftp и unicode разобрался. теперь встала проблема с сылками и размерностями массивов. В общем есть...

Перевыделение памяти или ещё какая-то ерунда?
цикл {...;font=createfont(...);selectobject(hdc,font);TextOut(...);...} должен повторяться любое кол-во раз, хоть бесконечность, но в...

Выделение памяти malloc realloc
мне задачу поставили, надо не используя stl, загрузить из файла данные. r - строки с - это столбцы выдается сообщение ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru