Перевыделение памяти realloc - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Есть двумерный массив char **inpWords, в который я добавляю слова из файла, отсеивая пробельные символы. из файла считываю посимвольно. Перед добавлением в массив проверяю, если памяти не хватает, то расширяю ее с помощью realloc. Как я понимаю, в 25 строке не происходит увеличение памяти. Как следствие, в 19 строке при countWord=2 вылетает ошибка, т.к. происходит обращение к неразмеченной области памяти (Ошибка: EXC_BAD_ACCESS (code=1, adress=0x33). Что я делаю не так?
    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);
        }
Только что доперло: проблема, видимо в том, что я создал указатели на массивы char*, а под сами массивы память не выделил. Тогда попутно вопрос такой: если есть массив char* mas, необходимо выполнить для него операцию free(mas). Можно передать указатель на массив в функцию и там освободить память?
void freeMem(char * array)
    free(array);

Решение задачи: «Перевыделение памяти realloc»

textual
Листинг программы
#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;
}

Объяснение кода листинга программы

  1. В начале программы объявляются переменные: N (количество символов в слове), M (количество слов), countWord (счетчик слов), index (счетчик символов в слове).
  2. Выделяется память под массив указателей на строки (char* inpWords) и под каждую строку (char inpWords[i]) с помощью функции malloc.
  3. В цикле while считывается ввод пользователя до конца файла.
  4. Если текущий символ не пробел и не знак препинания, то проверяется достаточно ли памяти в текущей строке (если индекс больше N). Если недостаточно, то память увеличивается на 15 символов и присваивается новому адресу.
  5. Если текущий символ пробел или знак препинания, то проверяется, была ли в строке какая-то информация (если index не 0). Если была, то она добавляется в строку как слово (в цикле for от 0 до M-1), индекс обнуляется и выводится на экран.
  6. Если в строке не было информации (index=0), то счетчик слов увеличивается на единицу и индекс обнуляется.
  7. Если счетчик слов равен M-1, то счетчик M увеличивается на 15 и память под массив указателей realloc.
  8. После выделения новой памяти, цикл while повторяется.
  9. В конце программы память освобождается с помощью функции free и возвращается 0.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.875 из 5
Похожие ответы