Доступ к указателю на символ в структуре, которая была приведена из пустого указателя
Я немного запутался по этому поводу:
Моя функция fillData(void* db)
должен быть передан указатель на структуру tdpatientProfile
, который содержится в структуре tdWAKDAllStateConfigure
как член по имени patientProfile
, У меня есть только void
Указатель 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 ответ
Это всего лишь догадка, но всякий раз, когда я вижу strncpy(), я нервничаю. Я уверен, что вы знаете, что strncpy() является злом в том смысле, что он не всегда правильно завершает строку назначения. Может ли это быть вашей проблемой?
Вы также можете подумать о том, чтобы arg3 из strncpy был sizeof(name)-1, или в любом случае что-то более безопасное, чем passChars.
Я готов поспорить, что проблема не имеет ничего общего с приведением void*: в конце концов, именно для этого void * и содержит указатель на любой тип. Если сравнить void * и char * после приведения, я думаю, вы увидите, что они по битам идентичны.