Есть некоторые классы для TCP сервера со следующим кодом:
// указатель на текущий класс
ik_server *g_pMainServer = NULL;
// функции
// обновить данные клиента
void updateClientData(ik_data_t &client_data)
{
if (g_pMainServer)
g_pMainServer->updateClientData(client_data);
};
// получить данные клиента
ik_data_t createDefaultClientData(unsigned long client_id)
{
if (g_pMainServer)
return g_pMainServer->createDefaultClientData(client_id);
return ik_data_t();
};
// класс ik_server
// предикант поиска в классе ik_server
struct _find_pred //: std::binary_function<unsigned long, unsigned long, bool>
{
unsigned long searchID; //
// конструктор
explicit _find_pred(const unsigned long ID)
{
searchID = ID;
};
//
bool operator () (const ik_data_t &ik)
{
if (ik.ik_id == searchID)
return true;
return false;
};
};
// тип данных - массив клиентов
typedef std::vector<ik_data_t> clientArray;
// конструктор
ik_server::ik_server()
{
...
g_pMainServer = this; // установить указатель на класс
};
// деструктор
ik_server::~ik_server()
{
g_pMainServer = NULL; // удалить указатель на класс
...
};
// получить данные клиента
ik_data_t ik_server::createDefaultClientData(unsigned long client_id)
{
// защитить процедуру при множестве потоков
// собственные классы, работают без замечаний
critical_section_keeper tmp(&m_class_section);
clientArray::iterator itData = m_clientArray.end();
ik_data_t Result;
// поиск с использованием предиканта
itData = std::find_if(m_clientArray.begin(), m_clientArray.end(), _find_pred(client_id));
// если клиент уже имеется в массиве - вернуть его данные
if (itData != m_clientArray.end())
{
Result = (*itData);
}
// клиента нет в массиве - создать новую структуру
else
{
Result.ik_id = client_id;
m_clientArray.push_back(Result);
};
return Result;
};
// обновить данные клиентов
void ik_server::updateClientData(ik_data_t &client_data)
{
critical_section_keeper tmp(&m_class_section);
clientArray::iterator itData = m_clientArray.end();
// поиск
itData = std::find_if(m_clientArray.begin(), m_clientArray.end(), _find_pred(client_data.ik_id));
if (itData != m_clientArray.end())
{
// в RELEASE попадаем сюда
MessageBoxW(0, L"Update client data", L"IK Server", MB_OK);
(*itData) = client_data;
}
else
{
// сюда по идее попадать не должны, но попадаем
// всегда в DEBUG
MessageBoxW(NULL, L"Error: IK ID not found", L"IK Server", MB_OK);
};
};
// класс ik_thread (отдельный поток)
// "шаг" потока
void ik_thread::nextStep()
{
int iResult = 0;
// получить сообщение от клиента
iResult = recv(m_client_ik.client_socket, &m_buffer[0], ul_buffer_size, 0);
// temporary
std::cout << "receiving: " << iResult << " bytes from ik." << std::endl;
if (iResult != 0)
{
unsigned long l_id = 0;
unsigned char ch_v = 0;
unsigned short sh_v = 0;
char *pID = new char[ul_buffer_size];
// получить ID клиента
memcpy(pID, &m_buffer[0], 9);
pID[9] = 0x00;
l_id = atol(pID);
// temporary
std::cout << "ik UIN = " << l_id << std::endl;
//
ik_data_t ik_t = createDefaultClientData(l_id);
/*
* логика опроса
*/
// temporary
std::cout << "send DATA\\n to ik..." << std::endl;
// получить данные клиента
memcpy(pID, "DATA\n", 6);
iResult = send(m_client_ik.client_socket, pID, 6, 0);
if (iResult != SOCKET_ERROR)
{
// temporary
std::cout << "DATA\\n is sending" << std::endl;
};
...
delete[] pID;
updateClientData(ik_t);
};
shutdown(m_client_ik.client_socket, SD_SEND);
closesocket(m_client_ik.client_socket);
m_transferComplite = true;
...
Код отладочный, для проверки работы, потом будет оптимизироваться...
Проблема в следующем:
MSVC2003 (VC7.1)
в DEBUG режиме функция ik_server::updateClientData получает _пустой_ вектор m_clientArray, при этом в ik_server::createDefaultClientData данные создаются и заносятся в вектор корректно (смотрел дебагером), при этом даже m_clientArray.end(), являющийся единственным элементом, отличается от того, что был на выходе ik_server::createDefaultClientData.
В RELEASE однако, поиск работает как положено (данные обновляются), но адреса и содержимое вектора просмотреть невозможно естественно.
З.Ы. есть вторая проблема в MSVC2008 (VC9.0)
Опять же в DEBUG в строке memcpy(pID, "DATA\n", 6) pID равен NULL

хотя до входа в ik_data_t ik_t = createDefaultClientData(l_id) он корректен.
Думается, что где-то течет или портится память, но тогда не понятно, почему я не вижу ни одной ошибки в RELEASE и более того, релизный вариант работает как задумывалось, а дебажный — нет.
Может кто сталкивался с подобным поведением вектора и подскажет метод поиска и устранения ошибки?
Здравствуйте, Tujh, Вы писали:
T>Есть некоторые классы для TCP сервера со следующим кодом:
T>Код отладочный, для проверки работы, потом будет оптимизироваться...
T>Проблема в следующем:
T>MSVC2003 (VC7.1)
T>в DEBUG режиме функция ik_server::updateClientData получает _пустой_ вектор m_clientArray, при этом в ik_server::createDefaultClientData данные создаются и заносятся в вектор корректно (смотрел дебагером), при этом даже m_clientArray.end(), являющийся единственным элементом, отличается от того, что был на выходе ik_server::createDefaultClientData.
T>В RELEASE однако, поиск работает как положено (данные обновляются), но адреса и содержимое вектора просмотреть невозможно естественно.
T>З.Ы. есть вторая проблема в MSVC2008 (VC9.0)
T>Опять же в DEBUG в строке memcpy(pID, "DATA\n", 6) pID равен NULL
хотя до входа в ik_data_t ik_t = createDefaultClientData(l_id) он корректен.
T>Думается, что где-то течет или портится память, но тогда не понятно, почему я не вижу ни одной ошибки в RELEASE и более того, релизный вариант работает как задумывалось, а дебажный — нет.
T>Может кто сталкивался с подобным поведением вектора и подскажет метод поиска и устранения ошибки?
Оптимизацию отключили в дебажном таргете?