我对智能指针有点困惑。在下面的代码中, & 运算符应该返回智能指针分配的地址还是它控制的指针的地址?
main() {
std::shared_ptr<int> i = std::shared_ptr<int>(new int(1));
std::shared_ptr<int> j = i;
printf("(%p, %p)\n", &i, &j);
}
Run Code Online (Sandbox Code Playgroud)
运行代码,我得到了不同的地址。如果我使用原始指针运行等效代码,我会得到相同的地址:
main() {
int e = 1;
int *k = &e;
int *l = k;
printf("(%p, %p)\n",k,l);
}
Run Code Online (Sandbox Code Playgroud) 关于glibc strlen中string.hin 的实现我有两个问题.
该实现使用带有"洞"的幻数.我无法理解这是如何工作的.有人可以帮我理解这个片段:
size_t
strlen (const char *str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, himagic, lomagic;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
/* All these elucidatory comments …Run Code Online (Sandbox Code Playgroud)Apple似乎声称Optional Swift 中的类型比nilObjective-C 更安全,但我不明白为什么会这样.
实现中哪些显着差异Optional更安全nil,以及这将如何影响我的代码?
鉴于int foo[] = {0, 1, 2, 3};我想知道指向过去"一个过去"的迭代器是否无效.例如:auto bar = cend(foo) + 1;
有大量的抱怨和警告,这是Stack Overflow问题中的"未定义行为",如下所示:c ++当过去结束迭代器时,迭代器+整数的结果是什么?不幸的是,唯一的来源是挥手.
我购买它的麻烦越来越多,例如:
int* bar;
Run Code Online (Sandbox Code Playgroud)
是未初始化的,但肯定不会调用未定义的行为,并且给定了足够的尝试,我确信我可以找到一个实例,其中未初始化的值bar具有相同的值cend(foo) + 1.
这里最大的困惑之一是我不会要求解除引用cend(foo) + 1.我知道这将是未定义的行为,标准禁止它.但是这样的答案:https://stackoverflow.com/a/33675281/2642059只引用解除引用这样的迭代器是非法的,不回答这个问题.
我也知道C++只保证它cend(foo)是有效的,但它可能会numeric_limits<int*>::max()在这种情况下cend(foo) + 1溢出.我对这种情况不感兴趣,除非它在标准中被调出,因为我们不能让迭代器超过"一个接一个结束".我知道这int*只是一个整数值,因此会受到溢出的影响.
我想从一个可靠的来源引用一个引用,即将迭代器移到"一个接一个"的元素之外是未定义的行为.
我有一段记忆,我正在"守卫",定义为
typedef unsigned char byte;
byte * guardArea;
size_t guardSize;
byte * guardArea = getGuardArea();
size_t guardSize = getGuardSize();
Run Code Online (Sandbox Code Playgroud)
为此目的可接受的实现是:
size_t glGuardSize = 1024; /* protect an area of 1kb */
byte * getGuardArea()
{
return malloc( glGuardSize );
}
size_t getGuardSize()
{
return glGuardSize;
}
Run Code Online (Sandbox Code Playgroud)
以下代码段可以为任何指针(来自不同的malloc,来自堆栈等)返回true吗?
if ( ptr >= guardArea && ptr < (guardArea + guardSize)) {
return true;
}
Run Code Online (Sandbox Code Playgroud)
该标准规定:
区域内的值将返回true.(当ptr是成员时,所有行为都正确.)
指针将是不同的(a == b只有它们是相同的).
所以我无法理解结果对于来自不同对象的任何指针的结果是否正确(因为它会破坏区域内其中一个指针的不同规则).
编辑:
检测指针是否在区域内的能力非常重要,在某些时候编写代码
if ( isInMyAreaOfInterest( unknownPointer ) ) { …Run Code Online (Sandbox Code Playgroud) 我无法理解函数签名和指针.
struct myStruct
{
static void staticFunc(){};
void nonstaticFunc(){};
};
int main()
{
void (*p)(); // Pointer to function with signature void();
p = &myStruct::staticFunc; // Works fine
p = &myStruct::nonstaticFunc; // Type mismatch
}
Run Code Online (Sandbox Code Playgroud)
我的编译器说类型myStruct::nonstaticFunc()是void (myStruct::*)(),但不是指向它的指针类型?
我问,因为当你创建一个std::function对象时,你传递了你想要它指向的函数的函数签名,比如:
std::function<void()> funcPtr; // Pointer to function with signature void()
not
std::function<void(*)()> funcPtr;
Run Code Online (Sandbox Code Playgroud)
如果我不得不根据void()我会说的模式猜测:
void myStruct::();
or
void (myStruct::)();
Run Code Online (Sandbox Code Playgroud)
但这不对.我不明白为什么我应该添加一个星号,因为它是非静态的而不是静态的.换句话说,指针void(* )()指向带签名的函数void(),而指针void(myStruct::*)()指向带签名的函数是什么?
我有一个问题 - 使用以下代码我试图找出存储在某个地址的内容以及我的静态变量存储在这个特定位置的时间.(我读到静态变量无限存储并且非常惊讶 - 想测试这是否属实).代码定义了一个静态变量(它在我的系统上的地址是0x1000020c0 - 这可能是相当随机的但是一直是这种情况)
如果我现在想要找出该地址存储的整数值,我必须先用$ number打印出地址,然后给出0x1000020c0.重新/重新解释地址(0x1000020c0)仅提供100!如果地址是在之前打印的,或者我在重新解释/重铸中使用&编号.
有人可以解释为什么会这样吗?
int static number = 100;
// std::cout << number << std::endl; <- prints 100
// prints 100 and the address 0x1000020c0 in my case
// std::cout << number << " " << &number << std::endl;
// this does not work unless &number is printed previously
// std::cout << "Value is : " << *reinterpret_cast<int*>(0x1000020c0) << std::endl;
// this does work and show the correct value (100)
std::cout << "Value is …Run Code Online (Sandbox Code Playgroud) size_t即使数组的大小不足以超过int的大小,我在索引数组时也需要始终使用它吗?
这不是我何时应该使用的问题size_t。我只想知道,例如,一个程序是否具有2GB的可用内存(所有这些字段都可以由int32索引),但是此内存(虚拟内存)已分配给“字段” 14GB-计算机的16GB内存。
在这种情况下,如果我使用int32而不是size_t(或unsigned long int)来索引内存,它将总是失败吗?
也许问题更多是关于虚拟内存,而不是指针。
我在这里有一个简单的示例:我使用类型别名using using关键字作为引用类型,然后我想知道是否可以通过指针运算符(*)使用该类型别名来声明对指针的引用:
int main(){
using ref_int = int&;
int x = 10;
int* p = &x;
//int*(&rpx) = p;
//ref_int * rptrx = p; // pointer to reference is not allowed.
*ref_int(rptrx) = p; // rptrx is undefined
}
Run Code Online (Sandbox Code Playgroud)
因为出于好奇,当我使用Element的类型时,std::vector<int>::reference我想将其与指针运算符结合*以声明对指针的引用:
int* ptr = new int(1000);
std::vector<int>::*(reference rptr) = ptr; // error: expected expression
Run Code Online (Sandbox Code Playgroud)但是我可以结合使用指针类型别名和引用运算符“&”来声明它:
using pInt = int*;
int i = 57;
int* ptrI = &i;
pInt(&rpInt) = ptrI;
cout << *rpInt << endl;
Run Code Online (Sandbox Code Playgroud)**我知道我没有指向引用的指针,因为引用只是已有对象的别名,而指针是一个对象,因此我们可以有一个指向它的指针或引用。
int a[] = {1, 2 ,3};
Run Code Online (Sandbox Code Playgroud)
我知道数组名称被转换为指针。一个经常使用的术语是它们衰减为指针。
然而对我来说, apointer是一个内存区域,它保存着另一个内存区域的地址,所以:
int *p = a;
Run Code Online (Sandbox Code Playgroud)
可以这样画:
----- -----
p ---------> a[0]. .....
----- -----
0x1 0x9
Run Code Online (Sandbox Code Playgroud)
但a它本身并不是指向另一个内存区域,它是内存区域本身。因此,当编译器将其转换为指针时,是将它(如p)保存在内存中的某处还是隐式转换?