Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.02.2012, 23:28   #1
_nic
 
Регистрация: 30.01.2010
Сообщений: 3
По умолчанию realloc VS memcpy - странный баг

Для отправки кой каких данных через сокеты.Написал класс,который собирает нужные данные вместе
Код:
#pragma pack(push, 1)
struct FileDir
{
	DWORD magic;
	int NumFls;
};
struct FileHead
{
	byte Id;
	DWORD sz;
};
#pragma pack(pop)

class PrepFile
{
private:
	char* mem;
	DWORD SZ;
	DWORD curpos;
	FileDir *FD;
public:
	PrepFile(DWORD magic)
	{
		this->SZ=4096;
		this->mem=(char*)malloc(this->SZ);
		this->FD=(FileDir*)this->mem;
		ZeroMemory(this->FD,sizeof(FileDir));
		this->curpos=sizeof(FileDir);	
		mem+=sizeof(FileDir);
		FD->magic=magic;
	}
	~PrepFile()
	{
		mem-=this->curpos;
		free(this->mem);
	}
	void AddFile(byte id,DWORD sz,char *file)
	{
		if( (sizeof(FileHead)+sz)>this->SZ)
		{
			DWORD OldSZ=this->SZ;
			this->SZ=this->SZ+(sizeof(FileHead)+sz);
			this->mem-=this->curpos;
			char *buf=new char[OldSZ];
			memcpy(buf,this->mem,OldSZ);
			realloc(this->mem,this->SZ);
			memcpy(this->mem,buf,OldSZ);
			delete []buf;
			this->mem+=this->curpos;
		}
		this->FD->NumFls++;
		FileHead *fh=(FileHead *)this->mem;
		this->curpos=this->curpos+sizeof(FileHead);
		this->mem+=sizeof(FileHead);
		ZeroMemory(fh,sizeof(FileHead));
		memcpy(this->mem,file,sz);//вылетает тут
		this->curpos=this->curpos+sz;
		this->mem+=sz;
		fh->Id=id;
		fh->sz=sz;
	}
	DWORD GetSz()
	{
		return this->SZ;
	}
	void CopyData(char *out)
	{
		mem-=this->curpos;
		memcpy(out,this->mem,this->SZ);
		mem+=this->curpos;
	}
};
Через один memcpy вылет,отладчик указывает на строчку
Код:
rep     movsd           ;N - move all of our dwords
без realloc ,такого не происходит.Где я ошибься?
_nic вне форума Ответить с цитированием
Старый 25.02.2012, 23:55   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

как бы realloc возвращает адрес нового блока памяти, а старый более недоступен, что и наблюдаем.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 25.02.2012, 23:58   #3
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

А Вы учли, что при расширении размера блока памяти функция realloc может переместить весь блок в новое расположение. Походу нет.
this->mem = realloc(this->mem,this->SZ);
И совершенно излишне пересохранять старые данные

Код:
char *buf=new char[OldSZ];
memcpy(buf,this->mem,OldSZ);
Чтобы потом запихнуть их обратно:
Код:
memcpy(this->mem,buf,OldSZ);
realloc их не сотрет при увеличении размеров блока.

Пока писал опус, ответили..

Последний раз редактировалось EUGY; 26.02.2012 в 00:00.
EUGY вне форума Ответить с цитированием
Старый 29.02.2012, 23:35   #4
_nic
 
Регистрация: 30.01.2010
Сообщений: 3
По умолчанию

Класс сейчас выглядит вот так:
Код:
class PrepFile
{
private:
	char* mem;
	DWORD SZ;
	DWORD curpos;
	FileDir *FD;
public:
	PrepFile(DWORD magic)
	{
		this->SZ=4096;
		this->mem=(char*)malloc(this->SZ);
		this->FD=(FileDir*)this->mem;
		ZeroMemory(this->FD,sizeof(FileDir));
		this->curpos=sizeof(FileDir);	
		mem+=sizeof(FileDir);
		FD->magic=magic;
	}
	~PrepFile()
	{
		mem-=this->curpos;
		free(this->mem);
	}
	void AddFile(byte id,DWORD sz,char *file)
	{
		if( (sizeof(FileHead)+sz)>this->SZ)
		{
			DWORD OldSZ=this->SZ;
			this->SZ=this->SZ+(sizeof(FileHead)+sz);
			this->mem-=this->curpos;
			this->mem=(char*)realloc(this->mem,this->SZ);
			this->mem+=this->curpos;
		}
		this->FD->NumFls++;
		FileHead *fh=(FileHead *)this->mem;
		this->curpos=this->curpos+sizeof(FileHead);
		this->mem+=sizeof(FileHead);
		ZeroMemory(fh,sizeof(FileHead));
		memcpy(this->mem,file,sz);
		this->curpos=this->curpos+sz;
		this->mem+=sz;
		fh->Id=id;
		fh->sz=sz;
	}
	DWORD GetSz()
	{
		return this->SZ;
	}
	void CopyData(char *out)
	{
		mem-=this->curpos;
		memcpy(out,this->mem,this->SZ);
		mem+=this->curpos;
	}
};
Но я напоролся еще на один баг.Причину которого в упор не вижу Внутри класса FileDir::NumFls имеет правильное значение ,но после того как достать данные из класса то стает равным нулю О_о
_nic вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странный баг в классе t2skler Общие вопросы C/C++ 3 15.01.2012 20:35
Странный баг... munthrekosh Паскаль, Turbo Pascal, PascalABC.NET 4 12.11.2011 10:24
Borderstyle - BsNone. Странный баг... MyLastHit Общие вопросы Delphi 2 21.12.2010 18:42
Странный баг при работе с разделяемой памятью в C mephisto123 Qt и кроссплатформенное программирование С/С++ 2 01.08.2008 18:10