Динамическое выделение памяти malloc, realloc на mega2560

mihart
Offline
Зарегистрирован: 14.05.2013

Добрый день!

Так как я не знаю сколько байт мне придет по Serial я решил воспользоваться динамическим выделением памяти:

Создаю переменные:

// указатель на следующий символ для записи в строке wifiterm
int wifitermoffset=0;
// строка для анализа парсером
char *wifiterm= (char*)malloc(sizeof(char));

Пишу данные:

    while (wifi.available()) { 
      if (wifiscanencode(wifi.read()))
        return true;
    }

В функции wifiscanencode при каждом поступившем символе wifitermoffser++, сам символ пишется

Если память заканчивается, то отрабатывает функция addmemory

  // если место в wifiterm закончилось, выделяем еще
  if (wifitermoffset > sizeof(wifiterm)) {
    wifiterm = addmemory(wifiterm);
  }

Код функции:

char *addmemory(char *term) {
  // каждый раз размер выделяемой памяти увеличиваем в два раза
  // перераспределяем память
  char *t = (char *)realloc(term, sizeof(wifiterm)*2);
  // если память не выделена, возвращаем NULL
  if (t == NULL) {
    free(term);
    return NULL;
  } 
  // копируем указатель обратно в term
  return t;
}

Я отметил строчку с realloc, в ней размер выделяемой памяти по указателю t должен быть больше в два раза.  Но этого не происходит, память остается того размера, что и была.

Что я делаю неправильно?

tsostik
Offline
Зарегистрирован: 28.02.2013

sizeof(wifiterm) - это не "сколько памяти выделено для этого указателя", а "сколько памяти занимает переменная типа указатель", то есть применительно к меге видимо 2 или 4 байта.

 

mihart
Offline
Зарегистрирован: 14.05.2013

Спасибо. 2 в данном случае.

Как узнать размер wifiterm?

strlen(wifiterm) посчитает количество символов до \0, то есть не даст реального размера.

Дело в том, что я не могу проверить, память реально выделилась или нет, потому как если переписать функцию так:

char *addmemory(char *term) {
return term;
}

То программа работает как и раньше, ведь символы я пишу так:

wifiterm[wifitermoffset]=c;

Вот и получается, что программа работает, но в какой-то момент пойдут глюки из-за того, что данные в heap вылезут куда не надо.

Как узнать размер выделенной памяти malloc'ом и как убедиться что при realloc'e действительно выделяется память?

tsostik
Offline
Зарегистрирован: 28.02.2013

Нужно завести еще одну глобальную переменную и хранить в ней размер выделенной памяти.

Кстати, при изначальном выделении памяти у вас тоже ошибка - вы выделяете памяти ровно один байт.

Надо как-то так:

char *wifiterm;
int memallocated = 100;
wifiterm = (char *) malloc( sizeof(char) * memallocated);
...
char * addmem(char *p){
    memallocated *= 2;
    p = (char *)realloc(p, sizeof(char)*memallocated);
    if(p=NULL) {
      //случилась беда - не хватает памяти. Это надо как-то обработать
    }
    return p;
}

Malloc выделяет ровно столько памяти в байтах, сколько ему передали в качестве аргумента. Если он не сможет выделить нужное количество - он возвращает NULL. То же самое касается и realloc.

mihart
Offline
Зарегистрирован: 14.05.2013

Понял. Первоначально я и использовал переменную, но попробовал от нее отказаться.

Спасибо, вопрос закрыт.