- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在做一个简单的测试,以数字的二进制表示形式计算1的数量:
int x;
while (cin >> x) {
bitset<32> xBitmap = {0};
xBitmap = static_cast<bitset<32>>(x);
std::cout << xBitmap.count() << std::endl;
}
上面的代码创建了正确的结果,但是当我使用一个指向位集的指针时,发生了意外情况:
bitset<32>* xBitmap = nullptr;
xBitmap = static_cast<bitset<32>*>((void*)&x);
std::cout << xBitmap->count() << std::endl;
此代码创建随机结果,每次使用“count()”都会创建不同的结果。我猜这是内存泄漏吗?但是为什么会导致内存泄漏呢?
最佳答案
您的第一个示例中发生了什么?
您有一个类型为int
的变量,并执行了static_cast
将int
转换为std::bitset<32>
。根据static_cast
(link)的规范:
static_cast<new_type>(expression)
- If there is an implicit conversion sequence from
expression
tonew_type
, or if overload resolution for a direct initialization of an object or reference of typenew_type
fromexpression
would find at least one viable function, thenstatic_cast<new_type>(expression)
returns the imaginary variableTemp
initialized as if bynew_type Temp(expression);
, which may involve implicit conversions, a call to the constructor ofnew_type
or a call to a user-defined conversion operator....
#include <iostream>
class A {
public:
A(int x) { std::cout << "A " << x << std::endl; }
};
int main(void) {
int y = 13;
A a = static_cast<A>(y);
}
运行该程序将打印
A 13
。这意味着在这种情况下
A a = static_cast<A>(y)
与
A a = A(y)
等效。这是因为
y
的类型为
int
,并且
A
的构造函数采用
int
。
A
的构造函数采用
std::string
,则程序将不再编译:
#include <iostream>
#include <string>
class A {
public:
A(std::string x) { std::cout << "A " << x << std::endl; }
};
int main(void) {
int y = 13;
A a = static_cast<A>(y);
}
编译器会抱怨无法将
int
转换为
A
。
#include <iostream>
class A {
public:
A(int x) { std::cout << "A " << x << std::endl; }
};
class B {
public:
B(A a) { std::cout << "B" << std::endl; }
};
int main(void) {
int y = 13;
B b = static_cast<B>(y);
}
此示例编译并打印:
A 13
B
因此,这就是规范称为“隐式转换序列”的内容。尽管没有用于
B
的
int
构造函数,但有用于
B
的
A
构造函数,然后又有用于
A
的
int
构造函数。因此
static_cast<B>(y)
将解析为
B(A(x))
。如果我们将
explicit
关键字添加到
A
的构造函数中,则该示例将不再编译:
explicit A(int x) { std::cout << "A " << x << std::endl; }
这是因为构造函数上的
explicit
关键字禁止在隐式转换序列中使用该构造函数。
static_cast<std::bitset<32>>(x)
时发生的情况。
std::bitset<N>
类具有一个采用
unsigned long
(
reference)的构造函数。构造函数未使用
explicit
关键字标记,因此它可以参与隐式转换序列。可以将
int
隐式转换为
unsigned long
。因此
static_cast<std::bitset<32>>(x)
解析为
std::bitset<32>((unsigned long)x))
,因此它创建了
std::bitset<32>
的新实例,并将
x
的值传递给构造函数。
int
的变量。您创建一个指向该变量的指针(
&x
),然后将该指针转换为
void
指针。然后,您将
static_cast
指针
void
指向
std::bitset<32>
指针。根据
static_cast
(
link)的规范:
- A prvalue of type pointer to
void
(possibly cv-qualified) can be converted to pointer to any object type.
std::bitmap<32>
的新实例。而是,
xBitmap
指向
x
的内存地址,但是将此内存解释为
std::bitmap<32>
。但是,存在一个问题:
std::bitmap<32>
的内存大小可能不等于
int
的内存大小。这是特定于实现的,因此C++标准库的不同实现可能对
std::bitmap<32>
具有不同的大小。
8
:
std::cout << sizeof(std::bitset<32>) << std::endl;
这意味着
std::bitset<32>
占用8个字节的内存。虽然32位当然只能用4个字节表示,但看来在我的系统上
std::bitset
总是会分配8个字节的倍数(即unsigned long)。例如,
sizeof(std::bitset<1>)
也是
8
,
sizeof(std::bitset<64>)
也是,但是
sizeof(std::bitset<65>)
是16,
sizeof(std::bitset<128>)
也是如此,但是
sizeof(std::bitset<129>)
是24,依此类推。
int
仅占用四个字节。因此,当我们获取
int
的内存但将其解释为
std::bitmap<32>
时,我们将从大小仅为4个字节的内存分配中读取8个字节(一个
std::bitmap<32>
的大小)。因此,我们将在
int
的存储器之后再读取四个字节。该内存中可能有任何东西,因此读取会导致未定义的行为。这就是为什么在调用
count()
时获得随机值的原因。它将计算
int
中的位数,之后还计算四个字节中的位数。
-fsanitize=address
标志启用它:
$ g++ -fsanitize=address test.cpp
$ ./a.out
123
=================================================================
==16616==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd1c7c5f80 at pc 0x55b34fd334b3 bp 0x7ffd1c7c5f00 sp 0x7ffd1c7c5ef0
READ of size 8 at 0x7ffd1c7c5f80 thread T0
因此,在这种情况下,地址清理会检测到您的程序试图读取超出分配大小的数据。
关于c++ - 将 `int*`转换为位集指针时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63464681/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
指针, C语言的精髓 莫队先咕几天, 容我先讲完树剖 (因为后面树上的东西好多都要用树剖求 LCA). 什么是指针 保存变量地址的变量叫做指针. 这是大概的定义, 但是Defad认为
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我是一名优秀的程序员,十分优秀!