我遇到了一些代码,其中指针在其声明的同一行使用。这是它的基本SSCCE:
#include "stdafx.h"
#include <iostream>
struct C
{
uint32_t a;
};
int main() {
C* pC = (C*) malloc(sizeof(*pC)); // <---- ???
pC->a = 42;
std::cout << pC << std::endl;
std::cout << pC->a << std::endl;
free(pC);
}
当我尝试使用uint32
执行类似操作时(在free()
之前插入):
uint32_t a = a + pC->a;
std::cout << a << std::endl;
然后为此语句打印任何内容,或者在调试随机值时存储在a
中,VS2015会给出运行时警告。执行后的错误级别是3.我知道这不起作用。
为什么我可以使用指针?它甚至合法吗?为什么编译器不抱怨这样的陈述?该陈述是否在幕后分成多个陈述?
答案 0 :(得分:3)
uint32_t a = a + pC->a;
会给您带来糟糕的结果,因为您在初始化之前使用a
的值,这是未定义的行为。有关详情,请参阅Why is 'int i = i;' legal?
C* pC = (C*) malloc(sizeof(*pC));
未在初始化中使用pC
的值。 sizeof
,当应用于命名变量时,会为您提供其类型的大小。这是一个未评估的操作数,这意味着它不会被评估。所以我们没有使用*pC
的值,而是获得指针指向C
的大小。
您希望这样做的一个原因是,如果您更改pC
的类型,则无需更改sizeof
部分。如果你有
C* pC = (C*) malloc(sizeof(C));
然后,您需要记住在更改sizeof(C)
的类型时更改pC
部分。
当然,使用std::unique_ptr
之类的
auto pC = std::make_unique<C>();
^ here is the only place you have to specify the type