Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> malloc() ошибка выделения памяти 
:(
    Опции темы
kurlyak
Дата 26.2.2012, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 7.11.2007

Репутация: нет
Всего: 3



Пишу на WinAPI, VS2005.
Есть у меня три файла- один с функцией WinMain(), другой файл с классом, третий файл с заголовком класса. Порядок вызова такой:
Код

//главный файл проекта
CTRLevelLoader g_TRLevelLoader;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int iCmdShow )
{
.....
Init();
,,,,,,
}

void Init()
{
.....
g_TRLevelLoader.ReadLevelFile("NameLevel.ph1");
.....
}

//файл заголовка класса:
class CTRLevelLoader
{
public:
//структура для файла для крации не приводится
TR2_Level * Level;
void ReadLevelFile(char *szFileName);
};

//файл реализации класса
void ReadLevelFile(char *szFileName)
{
...........

//тут ошибка выделения памяти, функция TR2alloc возвращает NULL
Level->Rooms[i].Lights = (struct tr2_room_light_struct *)TR2alloc(48 * Level->Rooms[i].NumLights);
...........
}

//функция выделения памяти
void *TR2alloc(int size)
{
   void *ReturnValue;

   if (size == 0)
      return(NULL);

   if ((ReturnValue = malloc(size)) == NULL)
      {
    return(NULL);
      }
   memset(ReturnValue, 0x00, size); // initialise it to NULL (better safe than sorry)
   return(ReturnValue);
}


Теперь вобщим о проблеме, а проблема вся в том, что у меня в функции ReadLevelFile() происходит множество вызовов TR2alloc() когда загружается файл уровня игры и выделяется память под нужные структуры. Так вот когда весь уровень из игры загружен (файл уровня 2 мегабайта) в самом конце функции ReadLevelFile() память перестает выделяться и внезапно функция TR2alloc() перестает выделять память. Прямо курьез какой- то - везде в программе память выделялась, а дошел до конца память перестала выделяться bad_alloc типа ошибка.

Пробывал использовать оператор new - то же самое. Я не очень разбираюсь, но функция malloc() выделяет память из кучи, у меня 2 Гига оперативки. 

кроме того есть аналогичная тестовая функция в другом проекте когда весь код класса из функции ReadLevelFile() заключен в WinMain() - то есть весь тот же код но без использования классов- все сделано в одном файле главном проекта. И этот тестовый код работает. А когда начал делать с классами проект, вызывать функцию из функций других пользовательских - то все, память перестает выделяться.

Что это может быть?
Заранее благодарен.
PM MAIL   Вверх
feodorv
Дата 26.2.2012, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(kurlyak @  26.2.2012,  18:02 Найти цитируемый пост)
48 * Level->Rooms[i].NumLights

48 - это правильное число? Может, лучше sizeof(struct tr2_room_light_struct) или что-то подобное?

Цитата(kurlyak @  26.2.2012,  18:02 Найти цитируемый пост)
   if ((ReturnValue = malloc(size)) == NULL)

Вызовите GetLastError() и напечатайте ошибку ;)


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
kurlyak
Дата 26.2.2012, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 7.11.2007

Репутация: нет
Всего: 3



Огромное спасибо feodorv!
Как то не додумал примостить GetLastError() в свой код - давно этой функцией не пользовался. Она вернула ошибку. Я по ошибке нашел в интернете как проверить состояние кучи памяти:

Код

char * MyHeapCheck()
{
// Check heap status
   int heapstatus = _heapchk();
   switch( heapstatus )
   {
   case _HEAPOK:
      return(" OK - heap is fine\n" );
      break;
   case _HEAPEMPTY:
      return(" OK - heap is empty\n" );
      break;
   case _HEAPBADBEGIN:
      return( "ERROR - bad start of heap\n" );
      break;
   case _HEAPBADNODE:
      return( "ERROR - bad node in heap\n" );
      break;
   }
}

void MyFunc()
{
//после каждого выделения памяти malloc()
char * szBuff = MyHeapCheck();
}


И потом нашел что в моей структуре я пользуюсь:

Код

char * FileName = {"LEVEL1.PHD"};
strcpy_s(Level->FileName,256, FileName);


После этого происходил сбой в куче памяти. Я поменял на старую функцию strcpy():

Код

typedef struct tr2_level_struct {
char   *FileName;                        
.....
} TR2_Level;    

char * FileName = {"LEVEL1.PHD"};
TR2_Level * Level;
......
strcpy(Level->FileName, FileName);


И все заработало. Но теперь следующий вопрос. После того как все заработало у меня предупреждения компилятора что я использую старую функцию strcpy() вместо новой strcpy_s(). Так вот - как мне сделать что бы в данном мое случае использовать char * FileName = {"LEVEL1.PHD"}; и новую функцию strcpy_s() в которой надо указать длинну строки. Когда я указываю длинну строки strcpy_s(Level->FileName, 256, FileName) то опять происходит сбой кучи памяти. Может поменят так:

Код

typedef struct tr2_level_struct {
char   FileName[256];                        
.....
} TR2_Level;    

char * FileName = {"LEVEL1.PHD"};
TR2_Level * Level;
......
strcpy_s(Level->FileName,256, FileName);


Так работает код, но у меня вопрос есть ли другие варианты с strcpy_s()?

Заранее благодарен за внимание.
PM MAIL   Вверх
volatile
Дата 26.2.2012, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(kurlyak @  26.2.2012,  19:27 Найти цитируемый пост)
После того как все заработало у меня предупреждения компилятора что я использую старую функцию strcpy() вместо новой strcpy_s(). 

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

Отключить такую заботу, можно так: (куда нибудь в главную шапку)
#define _CRT_SECURE_NO_WARNINGS

К тому-же strcpy_s() ище и непереносима.  (во всех смыслах  smile )
(это все конечно моё имхо.)

PM MAIL   Вверх
feodorv
Дата 26.2.2012, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(kurlyak @  26.2.2012,  19:27 Найти цитируемый пост)
И все заработало.

Это хорошо)))

Но, может, я чего-то не понимаю, но разве так можно:
Цитата(kurlyak @  26.2.2012,  19:27 Найти цитируемый пост)
typedef struct tr2_level_struct {
char   *FileName;                        
.....
} TR2_Level;    
char * FileName = {"LEVEL1.PHD"};
TR2_Level * Level;
......
strcpy(Level->FileName, FileName);

Если, конечно, после TR2_Level->FileName есть какой-то хвост, в который можно записать этот самый FileName, то всё в порядке. Но если он там действительно есть, то в 
Цитата(kurlyak @  26.2.2012,  19:27 Найти цитируемый пост)
strcpy_s(Level->FileName,256, FileName);

достаточно вместо 256 указать размер этого хвоста, и всё должно работать с strcpy_s. Не стоит в strcpy_s задавать абстрактный размер доступного пространства)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
kurlyak
Дата 28.2.2012, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 7.11.2007

Репутация: нет
Всего: 3



Понял, спасибо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0496 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.