Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于将指向char的指针转换为另一类型指针的问题 #包括 结构测试{ INTA; int b; }; int main(){ char*buffer=(char*)malloc(sizeof(char)*32);/#a char*ptr=buffer+4;/#b 新(ptr)测试;/#c char*ptr2=缓冲区+4;//#d 测试*tptr=重新解释铸件(ptr2);/#e tptr->a=1;/#f }_C++_Language Lawyer_C++20 - Fatal编程技术网

C++ 关于将指向char的指针转换为另一类型指针的问题 #包括 结构测试{ INTA; int b; }; int main(){ char*buffer=(char*)malloc(sizeof(char)*32);/#a char*ptr=buffer+4;/#b 新(ptr)测试;/#c char*ptr2=缓冲区+4;//#d 测试*tptr=重新解释铸件(ptr2);/#e tptr->a=1;/#f }

C++ 关于将指向char的指针转换为另一类型指针的问题 #包括 结构测试{ INTA; int b; }; int main(){ char*buffer=(char*)malloc(sizeof(char)*32);/#a char*ptr=buffer+4;/#b 新(ptr)测试;/#c char*ptr2=缓冲区+4;//#d 测试*tptr=重新解释铸件(ptr2);/#e tptr->a=1;/#f },c++,language-lawyer,c++20,C++,Language Lawyer,C++20,考虑上面的代码,在点#a处,分配函数malloc分配存储区域并隐式创建char[32]类型的数组对象,这在以下规则中提到: 有些操作被描述为在指定的存储区域内隐式创建对象。对于指定为隐式创建对象的每个操作,该操作在其指定的存储区域中隐式创建并启动零个或多个隐式生存期类型([basic.types])对象的生存期,如果这样做会导致程序具有定义的行为。如果没有这样一组对象会给出程序定义的行为,则程序的行为是未定义的。如果多个这样的对象集将给出程序定义的行为,则未指定创建哪一组这样的对象 因此,#b处

考虑上面的代码,在点
#a
处,分配函数
malloc
分配存储区域并隐式创建
char[32]
类型的数组对象,这在以下规则中提到:

有些操作被描述为在指定的存储区域内隐式创建对象。对于指定为隐式创建对象的每个操作,该操作在其指定的存储区域中隐式创建并启动零个或多个隐式生存期类型([basic.types])对象的生存期,如果这样做会导致程序具有定义的行为。如果没有这样一组对象会给出程序定义的行为,则程序的行为是未定义的。如果多个这样的对象集将给出程序定义的行为,则未指定创建哪一组这样的对象

因此,
#b
处的代码定义良好,因为指针
buffer
可以被视为指向数组的第一个元素,因此它满足规则。
#c
处的代码也有很好的定义,这将在
ptr
指向的存储器处构建一个类型测试对象
#d
#b
相同,定义也很好

但是,请考虑<代码>代码>代码>。现在,指针

ptr2
指向
数组
的第四个元素(由
malloc
创建),该元素是char类型的对象,由于存储被
Test
类型的对象重用,其生存期已结束。表达式
reinterpret\u cast(ptr2)
相当于
static\u cast(static\u cast(ptr2))

类型为“指向cv1 void的指针”的prvalue可转换为类型为“指向cv2 T的指针”的prvalue,其中T为对象类型,cv2与cv1相同或大于cv1。如果原始指针值表示内存中字节的地址A,而A不满足T的对齐要求,则结果指针值未指定。否则,如果原始指针值指向对象a,并且存在类型为T(忽略cv限定)的对象b可与a进行指针互换,则结果是指向b的指针。否则,指针值将通过转换保持不变

根据上述规则,
Test
类型的对象不能与char类型的对象进行指针互换。因此,我认为结果仍然是指向char类型的对象的指针,它是数组的第四个元素,只是它的生命周期已经结束

因此,我想知道
#f
处的代码是否有未定义的行为,因为
tptr
没有指向
Test
类型的对象?或者相反,指针
tptr
是否确实指向类型
Test
的对象,并且代码定义良好?如果我遗漏了一些其他规则,请指出

由于
tptr
未指向
Test
类型的对象,因此
#f
处的代码是否具有未定义的行为


#a
以来,程序具有未定义的行为,因为
malloc
被定义为触发隐式对象创建并返回指向适当创建对象的指针,但将给出其余程序定义行为的对象集为空。

我不认为
#a
#b
#c
#d
具有未定义的行为
#b
#d
是算术指针运算,只要它们指向数组的元素,这是正确的,因为
malloc
隐式创建了数组及其元素(类型为char)<代码>#c是由@jackX统治的,我不明白这样一句话的意思是什么,“提供程序定义行为其余部分的对象集是空的。”
malloc
无法创建将
#b
#f
都定义良好的对象。无论如何,即使您认为UB只在
#f
中触发,它之前的所有内容仍然有UB,因为@jackX这个句子并没有说以前的执行有未定义的行为,它只是说对这些执行没有要求。@jackX
buffer
指向
arr
的第一个元素。如果需要指向隐式创建的
测试对象的指针,则需要清洗
重新解释\u cast
-ed指针。@jackX您的意思是
tptr
?如果没有
#f
,那么是的,
ptr2
tptr
必须指向一个数组元素,一个
char
类型的对象。对我来说,
tptr
ptr
相同,它确实包含一个
Test
对象,所以我认为这个行为定义得很好。@Phil1970,
ptr2
指向char类型数组的一个元素,将这样一个指向
void
指针的指针转换为指向char类型对象的点值,则char类型指针与
Test
类型指针不可相互转换,因此该点值不变(这意味着结果仍然指向char类型的对象)。