Исключение Stackoverflow, возникающее в C ++ Codegear, а не в Visual C ++ - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть такой сценарий:

  • библиотека управления данными, написанная на Visual C ++, но загруженная и используемая в программе C ++, написанной с использованием библиотеки Embarcadero CodeGear
  • и функций, загруженных в программы LoadLibrary и GetProcAddress

проблема заключается в следующем:

  • библиотека в тестовой среде Visual C ++ работает нормально
  • программа аварийно завершает работу из-за исключения stackoverflow, использующего то же самоевызывающая последовательность функций с одинаковыми параметрами

упрощенный код для библиотеки:

struct TmRecordValue
{
    UINT8 RecordValue[128];
};
struct TmRecord{
    TmRecordValue RecordValues[2];
};
struct TmStruct
{
    UINT32 NumberOfRecords;
    TmRecord* Records;
};
void InitializeStruct(TmStruct* pStruct, int pNumberOfRecords)
{
    memset(pStruct, 0, sizeof(TmStruct));
    pStruct->NumberOfRecords = pNumberOfRecords;
    pStruct->Records = new TmRecord[pStruct->NumberOfRecords];
    memset(pStruct->Records, 0, sizeof(TmRecord) * pStruct->NumberOfRecords);
}
void AddRecordToStruct(TmStruct* pStruct, int pRecordIndex, char* pFirstValue, char* pSecondValue)
{
    strcpy_s(reinterpret_cast<char*>(pStruct->Records[pRecordIndex].RecordValues[0].RecordValue), 128, pFirstValue);
    strcpy_s(reinterpret_cast<char*>(pStruct->Records[pRecordIndex].RecordValues[1].RecordValue), 128, pSecondValue);
}

упрощенный код для программы:

TmStruct *struct1 = new TmStruct();
int RecordsQuantity = 100000;
InitializeStruct(struct1, RecordsQuantity);
for (int i = 0; i < RecordsQuantity; i++)
{
    AddRecordToStruct(struct1, i, "first", "second");
}

Комментарии:

  • программа работает нормально для RecordsQuantity = {10, 100, 1000, 10000}, но вылетает при 100000
  • , программа выдает исключение stackoverflow в функции AddRecordToStruct
  • , программа выбрасывает stackoverflowисключение всегда на фиксированной итерации (# 62643)
  • Я не вижу поведения рекурсии и больших переменных стека (все динамя бы сказал)
  • Я бы пошел с увеличением размера стека, но прежде чем я хотел бы проверить размер стека в тестовой среде Visual C ++ по размеру стека фактической работающей программы (но я незнать, как получить текущий размер стека потока)

Заранее спасибо,

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Проверьте правила вызова.Убедитесь, что вы используете cdecl везде или stdcall везде.

Поскольку по симптомам похоже, что библиотека Visual Studio - cdecl, но программа Embarcadero предполагает, что она равна stdcall, поэтому ни один стек не освобождается ни библиотекой, ни вызывающей стороной.

0 голосов
/ 25 февраля 2019

Вы используете sizeof(TmStruct) для указателя на TmRecord с:

memset(pStruct->Records, 0, sizeof(TmStruct) * pStruct->NumberOfRecords);
...