Используя «new» для динамического выделения памяти в C ++? - PullRequest
0 голосов
/ 09 июня 2011

Я работаю над кодом C ++ и у меня возникли некоторые проблемы с функцией, описанной ниже. Раньше я не пользовался большим количеством C ++, по крайней мере, долгое время, и поэтому я стараюсь учиться по мере продвижения вперед в значительной степени. Win32api тоже мало помогает с фактором путаницы ...

Функция успешно вызывается дважды, после чего происходит сбой при вызове на более поздней стадии, когда она вызывается в приложении.

PTSTR getDomainFromDN(PTSTR dnPtstr) {

size_t nDn=wcslen(dnPtstr);
size_t *pnNumCharConverted = new size_t;

wchar_t *szTemp = new wchar_t[10];          // for debugging purposes
_itow_s((int)nDn,szTemp,10,10);             // for debugging purposes

AddToMessageLog(EVENTLOG_ERROR_TYPE,szTemp);        // for debugging purposes (displays an integer value before failing)
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker A"));  // for debugging purposes
char *dn = new char[nDn];
    // !!!!!!!!!!!! all goes wrong here, doesn't get to next line, nDn does have a value when it fails (61)
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker B"));  // for debugging purposes

wcstombs_s(pnNumCharConverted,dn,nDn+1,dnPtstr,nDn+1);

...more code here...

delete[] dn;
delete pnNumCharConverted;

return result
}

Сначала я подумал, что это проблема с выделением памяти или что-то в этом роде, поскольку в строке char *dn = new char[nDn]; происходит сбой, последний маркер отображается как «Маркер А». Я использовал delete[] на указателе ниже, но безрезультатно. Я знаю, что nDn является значением, потому что я печатаю это в журнал сообщений, используя _itow_s для отладки. Я также знаю, что dnPtrstr является PTSTR.

Я пытался использовать malloc также с free() в старом стиле C, но это не улучшило ситуацию.

Ответы [ 3 ]

2 голосов
/ 09 июня 2011

Я попытался немного продезинфицировать ваш код.Одна из главных хитростей C ++ состоит в том, чтобы не использовать явно управление памятью, когда этого можно избежать .Используйте векторы вместо сырых массивов.Строки вместо символьных указателей.

И не нужно излишне динамически размещать объекты.Поместите их в стек, где они автоматически освобождаются.

И, как и на любом другом языке, инициализирует ваши переменные .

PTSTR getDomainFromDN(PTSTR dnPtstr) {
    std::wstring someUnknownString = dnPtstr;

    size_t numCharConverted = 0;

    std::wstring temp; // for debugging purposes
    std::ostringstream sstr;
    sstr << temp;
    AddToMessageLog(EVENTLOG_ERROR_TYPE,sstr.str().c_str());        // for debugging purposes (displays an integer value before failing)

    AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker A"));  // for debugging purposes
    std::vector<char> dn(someUnknownString.size());

    AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker B"));  // for debugging purposes

    wcstombs_s(&numCharConverted, &dn[0], dn.size(), someUnknownString.c_str(), dn.size());

    ...more code here...

    return result
}

Это может не иметьРешил вашу проблему, но она устранила большое количество потенциальных ошибок.Учитывая, что я не могу воспроизвести вашу проблему из предоставленного вами кода, это действительно лучшее, что я могу сделать.

Теперь, если бы вы могли придумать правильные имена вместо dnPtstr и dn, это может быть почти читаемым.;)

1 голос
/ 09 июня 2011

Я думаю, что ваша проблема в этой строке:

wcstombs_s(pnNumCharConverted,dn,nDn+1,dnPtstr,nDn+1);

, потому что вы говорите wcstombs_s скопировать до nDn + 1 символов в dn длиной всего nDn символов.

попробуйте изменить строку на:

wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,nDn);

или, возможно, еще лучше:

wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,_TRUNCATE);

я не уверен, как выотлаживаете это или как реализован AddToMessageLog, но если вы просто просматриваете журнал для отслеживания кода, а AddToMessageLog буферизует ваш журнал, то, возможно, ошибка возникает до того, как этот буфер очищен.

0 голосов
/ 09 июня 2011

Если вы уверены, что "char * dn = new char [nDn];"Ошибка, TRY "set_new_handler" -> http://msdn.microsoft.com/en-us/library/5fath9te(VS.80).aspx

В примечании стороны, несколько вещей:

  1. Самая первая операция "size_t nDn = wcslen (dnPtstr);"не на 100% правильно. Вы выполняете wcslen для dnPtstr, предполагая, что dnPtstr является юникодом.Однако это не так, поскольку это может быть PWSTR или PSTR в зависимости от того, определен ли UNICODE или нет. Итак, используйте _tcslen ().Лучше, если вы уделите некоторое время, чтобы разобраться с UNICODE, NON-UNICODE, так как они очень помогут вам в разработке Windows C ++.
  2. Почему вы используете так много «нового», если вы используете эти переменные только вэта функция (я предполагаю это). Предпочитайте стек над кучей для локальных переменных, если у вас есть определенные требования.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...