访问从 void 指针转换的结构中的 char 指针

Posted

技术标签:

【中文标题】访问从 void 指针转换的结构中的 char 指针【英文标题】:Accessing char pointer in a struct which was casted from a void pointer 【发布时间】:2012-02-03 13:00:47 【问题描述】:

我对此有点困惑:

我的函数fillData(void* db) 应该传递一个指向结构tdpatientProfile 的指针,该结构包含在结构tdWAKDAllStateConfigure 中作为名为@9​​87654324@ 的成员。我只有一个void 指针pData(这是一个tdWAKDAllStateConfigure 指针作为void* 传递),它是另一个结构Qtoken 的成员,所以我需要将void 指针转换为@987654331 @ 在我可以访问 patientProfile 之前。因为此时patientProfile 已经被取消引用,但我需要一个指向它的指针,所以我在开头添加了一个&

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

这在理论上应该可行,但patientProfile 有一个成员字符指针name[50],应该使用strncpy 填充。在filldata 中,我将void 指针投射回我的strncpy 调用中。

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

此时,我的代码崩溃了。我无法验证它是否正确转换,因为它们是 void 指针,所以我无法在调试器中查找它们,并且洞察力的内存视图不起作用,因为它运行在我连接的虚拟 ARM 平台上gdb/insight 来调试它。

经过 2 小时的测试和调试,我不明白。这里有人知道出了什么问题吗?

好的,更多代码,这不是公共代码,所以我会尽量减少它。

我有一个数据库线程,它调用一个应该从文件中读取值的函数。数据库线程有一个本地成员 Qtoken,其中包含一个 void 指针 pData,文件中的值应写入其中。数据库线程内部的函数调用是:

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

标题:

uint8_t unified_read(tdDataId datatype, void* db);

在统一读取中,我打开文件等并调用另一个函数,该函数应该将文件内的数据解析为;并将之前的字符复制到患者档案的字符名称[50] 中。解析函数的函数调用:

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

标题

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

在 parse 函数内部一切正常(ptr 需要是双指针,因为它需要增加,因为destinationSize 是正确的并且取消引用的ptr 也是如此),它会找到 ; 16 个字符后保存在passedChars 中。但是这个 strncpy 函数调用会破坏它并使我的代码崩溃:

strncpy(destination, *ptr, passedChars);

嗯,我应该补充一下:我在 2 周前遇到了这个问题,刚刚更改了代码,统一读取将指针传递给 tdWAKDAllStateConfigure 并自行取消引用患者配置文件。这工作得很好,但我的编码主管不想传递整个 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,它是一个 void 指针。这需要转换为 tdWAKDAllStateConfigure 指针,以便我可以获得指向它的成员 patientProfile(这是一个 tdPatientProfile)的指针。我的错在哪里?

【问题讨论】:

“字符指针name[50]”是指char *name[50]吗? 没有更多代码真的很难说。你只展示了两个代码片段,它们之间的关系并不清楚。 不,是字符名[50];在患者档案内。感谢提及 这些结构体的定义是什么? 【参考方案1】:

这不过是一个疯狂的猜测,但每当我看到 strncpy() 时,我都会感到紧张。我相信您知道 strncpy() 是邪恶的,因为它并不总是正确地终止目标字符串。那会是你的问题吗?

您可能还想考虑将 strncpy 的 arg3 设为 sizeof(name)-1,或者比passedChars 更安全。

我敢打赌,这个问题与强制转换 void* 无关:毕竟,这就是 void* for —— 持有指向任何类型的指针。如果在演员表之后比较 void* 和 char* ,我想你会发现它们是逐位相同的。

【讨论】:

passedChars 在我的测试用例中是 16,所以这应该不是问题。我在 strncpy 调用后终止它:destination[passedChars] = '\0'; // 空终止 (*ptr) += passChars + 1; - 代码在此语句之前崩溃。 @Jevermeister -- 但是崩溃发生在 strncpy() 之后,对吗?或者没有?如果是,则检查名称是如何终止的。有时(如果我没记错的话)strncpy() 将 NUL after 放在目标字符串的最后一个字符处,即在 name[passedChars + 1] 处。无论如何, strncpy() 绝对是一种不安全的复制字符串的方法。我自己再也不用它了。 (对于计数字符串,我总是使用 memmove(),这是可靠的。)(请指望我提供不请自来的建议 :-) 知道了。感谢您的回复。正确答案是 &(((tdWAKDAllStateConfigure *)(Qtoken.pData))->patientProfile) ,Qtoken.pData 前面的 ( 不见了... 太棒了!恭喜你找到了那个看不见的错字。

以上是关于访问从 void 指针转换的结构中的 char 指针的主要内容,如果未能解决你的问题,请参考以下文章

不能从const char *转换为LPCWSTR

从‘char *’初始化‘char’从指针生成整数而不进行强制转换

strcpy 从整数生成指针而不进行强制转换

从 void 指针转换为 char 指针时遇到问题

C++ 编译时提示:不能将参数 1 从“char [6]”转换为“LPCTSTR”

如何访问存储在char数组中的整数?