繁体   English   中英

C++ Void 双指针相互干扰

[英]C++ Void double pointer interference with another

我正在尝试做一个涉及重载 new 和 delete 的项目。 我在双空指针中存储了一个空指针数组(指向分配的随机内存的指针)。 当然,这个数组需要调整大小以考虑进来的更多空指针。

这是数组的初始化,allocArraySize(int) 设置为 4。

void** allocArray = (void**) calloc ( allocArraySize, sizeof(void*) );

将所有值设置为 nullptr..

for(int i=0; i<allocArraySize; i++){ *(allocArray + i*sizeof(void*)) = nullptr; }

但是,当尝试调整数组大小时,我注意到当我创建一个新的临时数组(temp)来存储它们时,我的原始空指针数组被修改了。

// PRINTS THE ORIGINAL ARRAY 
for(int i=0; i<allocArraySize; i++){std::cout<<i<<" = "<<*( allocArray + i*sizeof(void*))<<"\n";}

void** tempArray = (void**)calloc(allocArraySize, sizeof(void*));

// PRINTS THE ORIGINAL ARRAY 
for(int i=0; i<allocArraySize; i++){std::cout<<i<<" = "<<*( allocArray + i*sizeof(void*))<<"\n";}`

请注意,我什至还没有将数组值放入临时数组中,我仍然遇到这个问题。 这是为什么? 为什么这个随机值在它确实被初始化时被分配给这个点? 这个新的临时数组变量如何与我的数组混淆?

注意:这基本上是完整的代码。 唯一缺少的是主函数、iostream 和 allocArraySize 的声明。 是的,我知道我并没有释放这些可怜的双指针。 我只是想用最简单的方式来制造问题。

您正在错误地索引指针i * sizeof(void*)而不是i

for(int i=0; i<allocArraySize; i++){ allocArray[i] = nullptr; }

sizeof 乘数不应该存在:

*(allocArray + i*sizeof(void*))
//              ^^^^^^^^^^^^^^ this shouldn't be here

void**是强类型的。 它通过指针算法参与适当的偏移计算。 这里不需要 sizeof 偏移量计算。 该循环似乎是为了转储序列中的指针值而设计的,因此应该是:

for(int i=0; i<allocArraySize; i++)
{
    std::cout<< i << " = " << allocArray[i] << "\n";
}

首先,您不应该在 C++ 代码中使用 calloc。 特别是如果您的程序同时使用 new 表达式和 calloc\\malloc,则可能由于不匹配的删除器而导致 UB。

allocArraySize类型为void** ,因此它是指向指针的指针。 表达式*allocArraySize结果与void*uintptr_t类型的 sizeof 相同。 带指针的算术自动按指向相同类型的下一个对象所需的数量增加指针。

C++ 编写它的方法甚至不需要这种神秘的知识,您应该做的就是使用一个新表达式并使用空列表对其进行列表初始化,以获得与 C 中的calloc相同的效果。

void** allocArray = ::new void*[allocArraySize] {};

for(int i = 0; i < allocArraySize; ++i)
{
     std::cout<< i << " = " << allocArray[i] << "\n";
}

从重载的内部使用 new/delete 时,必须使用::否则会导致无限递归。

allocArray[i]等价于*(allocArray + i)

重载新\\删除放在一边。 但真正做到这一点的 C++ 方法是避免裸指针并尽可能使用容器。 New\\delete 可能是一些内存池类使用的包装器。

// do we really need a vector of pointers?
auto allocArray = std::vector<void*>(allocArraySize, nullptr);

int i = 0;
for( auto &v : allocArray )
    std::cout<< (i++) << " = " << v << "\n";

在 C++20 中,由于 init 语句,基于范围的 for 循环变得更加包含

for(int i = 0; auto &v : allocArray )
      std::cout<< (i++) << " = " << v << "\n";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM