Добавление определения std :: string приводит к нарушению прав доступа - PullRequest
1 голос
/ 19 декабря 2011

РЕДАКТИРОВАТЬ: Уважаемые будущие читатели, std :: string не имеет никакого отношения к проблеме.Это был неопределенный массив.

В двух словах, проблема состоит в том, что добавление объявления одной std :: string в программу, которая в противном случае содержит только C, вызывает ошибку «Место чтения нарушения доступа 0xfffffffffffffffe.»

В приведенном ниже коде, если строка, в которой объявлена ​​std :: string, закомментирована, программа завершается без ошибок.Однако, если строка остается в программе (без комментариев), программа завершает работу с вышеуказанной ошибкой нарушения доступа.Когда я открываю запущенную программу в отладчике VS2010, при обращении к ldap_search_sA () произошло нарушение прав доступа.

Обратите внимание, что объявленная std :: string никогда не используется.Это не должно использоваться, чтобы вызвать нарушение прав доступа.Простое объявление об этом приведет к нарушению прав доступа.

Я подозреваю, что это не имеет ничего общего с кодом LDAP, но я могу ошибаться.

int main() 
{
    try {
        // Uncommenting the next line causes an Access Violation 
        // at the call to ldap_search_sA().
        // std::string s;
        LDAP* pLdapConnection = ldap_initA("eu.scor.local", LDAP_PORT);
        ULONG version = LDAP_VERSION3;
        ldap_set_option(pLdapConnection, LDAP_OPT_PROTOCOL_VERSION, (void*) &version);         
        ldap_connect(pLdapConnection, NULL);
        ldap_bind_sA(pLdapConnection, NULL, NULL, LDAP_AUTH_NTLM);
        LDAPMessage* pSearchResult;
        PCHAR pMyAttributes[2];
        pMyAttributes[0] = "cn";
        pMyAttributes[1] = "description";
        ldap_search_sA(pLdapConnection, "dc=eu,dc=scor,dc=local", LDAP_SCOPE_SUBTREE,  "objectClass=computer)", pMyAttributes, 0, &pSearchResult);    
    } catch (...) {
        printf("exception\n");
    }
    return 0;
}

Ответы [ 3 ]

4 голосов
/ 19 декабря 2011
    PCHAR pMyAttributes[2];
    pMyAttributes[0] = "cn";
    pMyAttributes[1] = "description";

Массив атрибутов должен заканчиваться NULL:

    PCHAR pMyAttributes[3];
    pMyAttributes[0] = "cn";
    pMyAttributes[1] = "description";
    pMyAttributes[2] = NULL;
2 голосов
/ 19 декабря 2011

Я не знаю, что такое ldap_search_sA, но функция ldap_search в OpenLDAP получает указатель на завершенный массив с нулевым указателем char*. Массив, который вы передаете, неправильно завершен, поэтому все может бывает. Я бы рекомендовал использовать std::vector<char*> для этого, в общем, и обернуть вызовы в функцию C ++, которая систематически постфиксирует терминатор, так что вы не забудете. Хотя в таких простых случаях:

char* attributes[] = { "cn", "description", NULL };

сделает свое дело. Это, вероятно, вызовет предупреждение; это действительно должно быть:

char const* attributes[] = { ... };

Но интерфейс OpenLDAP является устаревшим C, который игнорирует const, так что вы бы нужен const_cast на сайте звонка. (Еще один аргумент для упаковки функция.)

Наконец, я настоятельно рекомендую вам сбросить запутывающий typedef s как PCHAR; они просто делают код менее понятным.

1 голос
/ 19 декабря 2011

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

Я заметил, чтоВы вызываете несколько функций без проверки их возвращаемых значений, даже если в спецификацию этих функций не входит выдача исключений.Таким образом, если какая-либо из этих функций завершается с ошибкой (начиная с ldap_initA), и вы продолжаете предполагать, что она не сработала, вы можете получить повреждение памяти.Вы проверяли это?

...