Доступ к указателю на символ в структуре, которая была приведена из пустого указателя - PullRequest
0 голосов
/ 05 января 2012

Я немного запутался по этому поводу:

Моей функции fillData(void* db) должен быть передан указатель на структуру tdpatientProfile, которая содержится в структуре tdWAKDAllStateConfigure как член с именем patientProfile. У меня есть только void Pointer pData (который является tdWAKDAllStateConfigure указателем, переданным как void*), который является членом другой структуры Qtoken, поэтому мне нужно привести void указатель к tdWAKDAllStateConfigure прежде чем я смогу получить доступ patientProfile. Поскольку в этот момент patientProfile уже разыменовано, но мне нужен указатель на него, я добавляю & в начало.

&(((tdWAKDAllStateConfigure*)Qtoken.pData)->patientProfile)

Это должно работать теоретически, но patientProfile имеет указатель на символ члена name[50], который должен быть заполнен с помощью strncpy. Внутри filldata я бросил указатель void обратно в мой strncpy вызов.

strncpy(((tdPatientProfile*)db)->name, sourcestring, passedChars)

В этот момент мой код дал сбой. Я не могу проверить, правильно ли он приведен, потому что это пустые указатели, поэтому я не могу найти их в отладчике, и представление о памяти не работает, потому что оно работает на виртуальной платформе ARM, где я соединяюсь с GDB / Insight для его отладки.

После 2 часов тестирования и отладки я не понимаю. Кто-нибудь здесь понял, что идет не так?

хорошо, больше кода, это не публичный код, поэтому я постараюсь сократить его до минимума.

У меня есть поток базы данных, который вызывает функцию, которая должна читать значения из файла. Поток базы данных имеет локальный член Qtoken, который содержит пустой указатель pData, в который следует записывать значения из файлов. Вызов функции внутри потока базы данных:

unified_read(dataID_PatientProfile,&(((tdWAKDAllStateConfigure*)Qtoken.pData)->patientProfile))

Заголовок:

uint8_t unified_read(tdDataId datatype, void* db);

Внутри unified_read, я открываю файл и т. Д. И вызываю другую функцию, которая должна анализировать данные внутри файла; и скопируйте предыдущие символы в имя символа [50] PatientProfile. Вызов функции для функции разбора:

parseString(&ptr, ((tdPatientProfile*)db)->name, 50);

Заголовок

uint8_t parseString(char** ptr, char* destination, size_t destinationSize)

внутри функции разбора все в порядке (ptr должен быть двойным указателем, потому что его нужно увеличить, это работает, так как destinationSize корректно и разыменованный ptr тоже), он найдет; после 16 символов и сохраняет его в пройденных символах. Но этот вызов функции strncpy ломает ее и приводит к сбою моего кода:

strncpy(destination, *ptr, passedChars);

Ах, хорошо, я должен добавить: у меня была эта проблема 2 недели назад, и я просто изменил код, который unified_read получает указатель на tdWAKDAllStateConfigure и разыменовывает PatientProfile самостоятельно. Это сработало отлично, но мой начальник по кодированию не хочет передавать весь tdWAKDAllStateConfigure только для изменения элемента PatientProfile внутри него.

Еще один тест:

tdPatientProfile testomat;
char str1[]= "To be or not to be";
strncpy(testomat.name, str1, 15);

if(!unified_read(dataID_PatientProfile,&testomat))

это работает как задумано. Поэтому мое приведение & (((tdWAKDAllStateConfigure *) Qtoken.pData) -> PatientProfile), по-видимому, неверно.

Помните: я получил pData, который является пустым указателем. Это должно быть приведено к указателю tdWAKDAllStateConfigure, чтобы я мог получить указатель на его член PatientProfile (который является tdPatientProfile). Где моя вина?

1 Ответ

0 голосов
/ 05 января 2012

Это не что иное, как дикое предположение, но всякий раз, когда я вижу strncpy (), я нервничаю. Я уверен, что вы знаете, что strncpy () является злом в том смысле, что он не всегда правильно завершает строку назначения. Может ли это быть вашей проблемой?

Вы также можете подумать, чтобы arg3 из strncpy был sizeof (name) -1, или в любом случае что-то более безопасное, чем passChars.

Я готов поспорить, что проблема не имеет ничего общего с разыгрыванием пустоты *: вот что пустота * это для , в конце концов - для удержания указателя на любой тип. Если сравнить void * и char * после приведения, я думаю, вы увидите, что они битовые биты идентичны.

...