在运行时检查指针后面的数据以避免段错误:(wchar_t *) 与 (char *)
Checking data behind pointer at runtime to avoid segfaults : (wchar_t *) vs. (char *)
我有一个类似 printf
的函数,可以处理 %s
(char *
) 和 %ls
(wchar_t *
) 转换。如果我为正确的 conv 说明符传递正确的参数,一切正常。
但是如果我在函数需要 wchar_t *
时将 char *
传递给它,它可能会出现段错误(空终止字节位于 wchar_t
的第二个字节实例)。由于我通过 va_arg()
访问此参数,因此我无法确定类型。
如果我认为这个 char
数组总是以 NUL 结尾,我可以逐字节检查以正确处理以 NUL 结尾的字符并在它之后停止内存访问。但是这样我就无法处理 wchar_t
这样的合法值:
0b XXXXXXXX XXXXXXXX 00000000 XXXXXXXX
我已经在使用 __attribute__
printf GNU C 扩展。但是我这个函数可能被 python 程序通过 ctypes
使用,所以 format/type 在编译时检查可能还不够。
有没有办法在我的 C 函数中在运行时执行此类检查?
(NB : "There is no such way" 可能是答案,但我仍然在询问以确保完全确定。)
不,这不可能。
在典型的 C 实现中,类型系统仅作为编译时的辅助工具存在。*在运行时,您所拥有的只是数据字节,甚至没有办法从数字中区分指针(除了受过教育的猜测)。
从技术上讲,如果原始参数不是 char*
、signed char*
、unsigned char*
或 [=,您甚至不允许 va_arg(ap, const char*)
然后检查内存14=],或此类类型的 const
相关版本。传递给 va_arg
的类型始终需要是兼容类型。 (一个原因是不能保证指向不同类型的指针具有相同的大小、布局和含义。)
(*在 C++ 中,这个故事有点多,因为表示类型的数据存储时连接到多态对象以使 dynamic_cast
和 typeid
正常工作,并与所有异常对象相关联以使 catch
块正常工作。但是 none 与 va_arg
兼容。)
我有一个类似 printf
的函数,可以处理 %s
(char *
) 和 %ls
(wchar_t *
) 转换。如果我为正确的 conv 说明符传递正确的参数,一切正常。
但是如果我在函数需要 wchar_t *
时将 char *
传递给它,它可能会出现段错误(空终止字节位于 wchar_t
的第二个字节实例)。由于我通过 va_arg()
访问此参数,因此我无法确定类型。
如果我认为这个 char
数组总是以 NUL 结尾,我可以逐字节检查以正确处理以 NUL 结尾的字符并在它之后停止内存访问。但是这样我就无法处理 wchar_t
这样的合法值:
0b XXXXXXXX XXXXXXXX 00000000 XXXXXXXX
我已经在使用 __attribute__
printf GNU C 扩展。但是我这个函数可能被 python 程序通过 ctypes
使用,所以 format/type 在编译时检查可能还不够。
有没有办法在我的 C 函数中在运行时执行此类检查?
(NB : "There is no such way" 可能是答案,但我仍然在询问以确保完全确定。)
不,这不可能。
在典型的 C 实现中,类型系统仅作为编译时的辅助工具存在。*在运行时,您所拥有的只是数据字节,甚至没有办法从数字中区分指针(除了受过教育的猜测)。
从技术上讲,如果原始参数不是 char*
、signed char*
、unsigned char*
或 [=,您甚至不允许 va_arg(ap, const char*)
然后检查内存14=],或此类类型的 const
相关版本。传递给 va_arg
的类型始终需要是兼容类型。 (一个原因是不能保证指向不同类型的指针具有相同的大小、布局和含义。)
(*在 C++ 中,这个故事有点多,因为表示类型的数据存储时连接到多态对象以使 dynamic_cast
和 typeid
正常工作,并与所有异常对象相关联以使 catch
块正常工作。但是 none 与 va_arg
兼容。)