将指针转换为int和字符之间有什么区别吗?在C ++中

问题描述 投票:0回答:2
#include <iostream>

char** make2D(const int dim1, const int dim2)
{
    char* toAlloc;
    const int size = (dim1 * dim2) + dim2;
    toAlloc = new char[size];

    for(int i = 0; i < dim2; i++)
    {
        toAlloc[i] = reinterpret_cast<char>(&toAlloc[(dim2 + (dim1 * i))]);
    }

    return reinterpret_cast<char**>(toAlloc);
}

int main(void)
{
    int dim1 = 8;
    int dim2 = 10;
    char** array2D = make2D(dim1, dim2);

    for (int i = 0; i < dim2; ++i)
    {
        array2D[i][i % dim1] = i + 100; // << Crash
    }

    return 0;
}

我试图通过单个分配来分配二维数组。所以,我的算法是,前10个(这个代码中的dim2)项目具有指向每行的第一项的指针。

当我通过指向'int'的方式尝试这个时,

int** make2D(const int dim1, const int dim2)
{
    int* toAlloc;
    const int size = (dim1 * dim2) + dim2;
    toAlloc = new int[size];

    for(int i = 0; i < dim2; i++)
    {
        toAlloc[i] = reinterpret_cast<int>(&toAlloc[(dim2 + (dim1 * i))]);
    }

    return reinterpret_cast<int**>(toAlloc);
}

int main(void)
{
    int dim1 = 8;
    int dim2 = 10;

    int** array2D = make2D(dim1, dim2);

    for (int i = 0; i < dim2; ++i)
    {
        array2D[i][i % dim1] = i + 100;
    }

    return 0;
}

它工作正常,但当我在char中执行此操作时,它在上面的代码中的注释行崩溃。

我对崩溃的想法是当我做reinterpret_cast时,由于指针(8byte)和char(1byte)之间的内存大小差异而发生了一些事情。所以,听起来很荒谬......将指针(8byte)更改为int(4byte)很好,但是当我进行更大幅度的渲染(8byte到1byte)时,会导致一些问题......

我不知道为什么char不起作用但int工作。你能提出一些建议来使char案件有效吗?

c++ memory-management allocation reinterpret-cast
2个回答
0
投票

回答这个问题是有一个区别,一个巨大的,在很多平台上,一个指针可能适合一个int,在很少的平台上它将适合一个char。在64位的现代PC上,没有一种是存储指针的安全方法。

如果尺寸是静态的,请使用vectorarray等容器。尝试类似的东西:

array<array<T, dim2>, dim1> variable{};

如果你真的想要一个T型的二维数组;因为你似乎需要一个指针数组尝试类似的东西:

array<array<T *, dim2>, dim1> variable{};

这将为你的平台制作一个适当类型的数组存储指针,无论实际指针有多大,显然你应该用你要指向的数据的正确类型替换T,这将确保指针数学是适合你的。数组类型的大小将在编译时计算,如果你需要动态大小,你应该使用向量,在向量上调用resize和所有子向量之后,确保尽可能少地分配所有内存。

也请不要使用reinterpret_cast或c-style演员,除非你非常清楚自己在做什么,否则它会成为灾难的秘诀。

不知道你正在读什么书或谁教你C ++,但请改变你的知识来源。

不鼓励使用原始拥有指针,并且在很多方面使用它们的方式都是错误的。切勿将指针存储在除指针类型之外的任何内容中。即使在平原C中,如果你需要施放,你至少应该施展至无效*。

如果你真的想直接存储/传递指针,请阅读unique_ptrshared_ptr

如果您坚持使用容器的原始指针,请尝试使用清理程序(如地址清理程序,内存清理程序)来构建代码(这些至少由clang和gcc支持,现在可能更多的编译器)


0
投票

问题是对象大小的“不兼容性”:

  • sizeof(char)1
  • sizeof(int)通常是48(但至少2)。
  • sizeof(T*),一般是48std::uintp_t可以保持void*值,这对于int不太必要(甚至更少与char)。

你不能安全地将void*存放到charint。它发生在为int工作,但它不便携。

reinterpret_cast通常是错误的工具。

更简单的是创建一个class Matrix,使用std::vector<T>和accessor来修复索引。 (你甚至可能有代理允许m[2][3]语法)。

拥有原始指针,您需要新的展示位置,并提供正确的删除...

© www.soinside.com 2019 - 2024. All rights reserved.