C переполнение памяти (v2) - PullRequest
       8

C переполнение памяти (v2)

2 голосов
/ 27 октября 2010

РЕДАКТИРОВАТЬ: обновлен код с новой ссылкой Pastebin, но он все еще останавливается на цикле info-> граждан [x] -> имя во время.Добавил realloc в циклы и привел код в порядок.Будем благодарны за любые комментарии.

У меня есть несколько проблем с переполнением памяти

http://pastebin.com/vukRGkq9 (v2)

Неважночто я пытаюсь, просто недостаточно памяти выделяется для информации-> граждан, и GDB часто говорит, что он не может получить доступ к информации-> граждан [x] -> имя.

Иногда я даже получаюОшибки KERN_INVALID_ADDRESS сразу после операторов printf для strlen (Strlen не используется в коде в тот момент, когда gdb останавливается из-за ошибки, но я предполагаю, что printf каким-то образом использует strlen).Я думаю, это как-то связано с тем, как распределяется структура памяти.Так что мне интересно, может кто-нибудь взглянуть?

Ответы [ 5 ]

7 голосов
/ 27 октября 2010

Вы не должны делать malloc(sizeof(PEOPLE*)), потому что он выделяет точное количество байтов для указателя (4 байта на 32-битной арке).
Кажется, что вы хотите сделать, это malloc(sizeof(PEOPLE) * N), где N - макс.количество людей, которых вы хотите поместить в этот блок памяти.

3 голосов
/ 27 октября 2010

Очевидно, что проблема заключается в:

info->citizens = malloc(sizeof(PEOPLE *));
info->citizens[0] = malloc(sizeof(PEOPLE *));
info->citizens[1] = malloc(sizeof(PEOPLE *));

Логично подумайте, что вы пытаетесь сделать здесь.

1 голос
/ 27 октября 2010

В ваших структурах почти наверняка не должно содержаться таких членов, как:

time_t *modtimes;
mode_t *modes;
bool *exists;

Вместо этого вы должны просто использовать:

time_t modtimes;
mode_t modes;
bool exists;

Таким образом, вам не нужно их динамически распределять,или впоследствии отпустите их.Причины в том, что а) они маленькие и б) их размер известен заранее.Вы будете использовать:

char *name;

для строкового поля, потому что оно не маленькое, и вы заранее не знаете, насколько оно велико.

В другом месте кода, у вас есть следующее:

if(top)
{
  PEOPLE *info;
  info = malloc(sizeof(PEOPLE *));
}

Если top имеет значение true, тогда этот код выделяет указатель, а затем сразу же пропускает его - область действия второго info ограничивается оператором if, поэтому вы не можете использовать его позже и не можете выпустить позже.Вам нужно сделать что-то вроде этого:

PEOPLE *process(PEOPLE *info, ...)
{
  if (top)
  {
    info = malloc(sizeof(PEOPLE));
  }

  info->name = strdup("Henry James");
  info->exists = true;
  return info;
}
0 голосов
/ 27 октября 2010

Много проблем с выделением памяти с этим кодом.Упомянутые выше и многие другие, например:

info->citizens[masterX]->name = malloc(sizeof(char)*strlen(dp->d_name)+1);
info->citizens[masterX]->name = dp->d_name;

Вы не можете копировать строки в C посредством присваивания (используя =).Вы можете написать это как:

info->citizens[masterX]->name = malloc(strlen(dp->d_name)+1);
strcpy(info->citizens[masterX]->name, dp->d_name);

Или вы можете сжать весь файл выделения и копирования следующим образом:

info->citizens[masterX]->name = strdup(dp->d_name);

Аналогично в строках 143/147 (за исключением того случая, когдавыделил один байт слишком мало в вашем вызове malloc).

0 голосов
/ 27 октября 2010

Кажется, у вас слишком много уровней косвенности. Почему вы используете **citizens вместо *?

Кроме того, кроме того факта, что вы выделяете пространство для указателя, а не для структуры, есть пара странных вещей, например, локальная переменная info в строке 31 означает, что первоначальное распределение находится вне области как только блок закрывается в строке 34.

Вам нужно более четко подумать о том, какие данные находятся.

...