2012-02-11 3 views
1

Я никогда не делал никаких работ на C++/COM раньше, поэтому я пытаюсь захватить существующее решение и просто изменить его на мои нужды. Проект был написан и успешно скомпилирован с VC 6, и я пытаюсь работать с ним сейчас в 2010 году. Мне пришлось изменить несколько ссылок, чтобы их компилировать, но по какой-то причине генерируемая DLL вызывает исключение из моя система (оригинал прекрасно работает). Проводя некоторые исследования ошибки, похоже, что я получаю переполнение буфера, когда пытаюсь объявить массив символов.Переполнение буфера при объявлении Char Array

bool CFile::simpleWrite(char* cData) 
{ 
    try{ 

     // temp result variable 
     BOOL bResult = 0; 

     // file handle 
     HANDLE hFile = INVALID_HANDLE_VALUE; 

     // get the CMain singleton 
     CMain* m_pMain = CMain::GetInstance(); 

     // this point gets synchronization to ensure we get unique file name... 
     char cDirFilename[MAX_PATH + 1]; 
     GetLogFileName(cDirFilename, MAX_PATH); 

     // sanity check 
     if(strcmp(cDirFilename, "c:\\") == 0) assert(0); 

     // try and create a file 
     hFile = CreateFile(cDirFilename, GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

     // if have a good file handle 
     if(hFile != INVALID_HANDLE_VALUE){ 

      size_t lenFileData = strlen(cData) + 72; 
      char* cFileData = new char[lenFileData]; 
      _snprintf(cFileData, lenFileData, "<?xml version=\"1.0\"?>\r\n<RootElement>\r\n%s</RootElement>\r\n\0", cData); 
... 

Вот объявление/назначение для cData (cXML в вызывающем методе).

char cXML[EVENT_LOG_MAX_MESSAGE]; 
// get the CMain singleton 
CMain* pMain = CMain::GetInstance(); 

long lThreadID = GetCurrentThreadId(); 

// put the parameters into XML format 
pMain->BuildXML(cXML, EVENT_LOG_MAX_MESSAGE,errLogLevel,userActivityID,methodName,lineNumber,className,AppID,errorDescription,errorID,lThreadID); 

// write the data to file 
if(!simpleWrite(cXML)) 
... 

BuildXML делает _snprintf в CXML и вернуть его.

Вот стоп-кадр, идущий от моего вызова в некоторые файлы VC.

Test.dll!_heap_alloc_base(unsigned int size) Line 55 C 
Test.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 431 + 0x9 bytes C++ 
Test.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 239 + 0x19 bytes C++ 
Test.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Line 302 + 0x1d bytes C++ 
Test.dll!malloc(unsigned int nSize) Line 56 + 0x15 bytes C++ 
Test.dll!operator new(unsigned int size) Line 59 + 0x9 bytes C++ 
Test.dll!operator new[](unsigned int count) Line 6 + 0x9 bytes C++ 
Test.dll!CFile::simpleWrite(char * cData) Line 87 + 0xc bytes C++ 

Я уверен, что есть какая-то глупая основная ошибка, но я не могу понять, как это понять.

+0

Не могли бы вы предоставить более подробную информацию о 'cData'? –

+1

72 - английский номер. Программисты используют 256. Фрагмент кода, конечно, совершенно бессмыслен. –

+0

Я добавил несколько дополнительных сведений о cData, но просто хотел напомнить, что этот проект компилируется и работает отлично, когда он построен в VS 6. Этот код используется несколько лет и не был изменен с 2007 года. – JStinebaugh

ответ

0

Ваша ошибка, скорее всего, где-то еще, где вы закончите разлагать кучу. Я замечаю, что вы используете strlen здесь, не добавляя один для завершающего нуля. Посмотрите в своем коде, чтобы узнать, используете ли вы strlen для выделения памяти и копирования где-нибудь, потому что я думаю, что вы развращаете кучу, выделяя один байт слишком мало, а затем strcpy'ing к нему.

+1

Если бы мысль ; посмотрите, где вы выделяете cData и копируете его. Вы случайно делаете cData = новый char [strlen (oldString)]; strcpy (cData, oldString)? Это приведет к повреждению кучи, поскольку завершение 0 перезаписывает конец буфера. – Tobias

0

Как я и подозревал, это была моя собственная глупость. У этого приложения COM была зависимость, о которой я не знал. Никогда не видел ничего, пытаясь найти его в мониторе процесса, и, по-видимому, проект имел локальную копию файла для компиляции. Спасибо за ввод, хотя.

Смежные вопросы