C++ 使用new而不是malloc分配mem

C++ 使用new而不是malloc分配mem,c++,pointers,C++,Pointers,我正在尝试使用new而不是malloc来计算此代码的精确等效项。指向浮点数组[4]指针的指针: float (**f)[4] = (float(**)[4])malloc(2 * sizeof(float(*)[4])); for (int p = 0; p < 2; p++) { f[p] = (float(*)[4])malloc(3 * sizeof(float[4])); } 我不确定。。。 但是试试这个: float **f[4]; for(int i = 0;

我正在尝试使用
new
而不是
malloc
来计算此代码的精确等效项。指向浮点数组[4]指针的指针:

float (**f)[4] = (float(**)[4])malloc(2 * sizeof(float(*)[4]));
for (int p = 0; p < 2; p++) {
    f[p] = (float(*)[4])malloc(3 * sizeof(float[4]));
}
我不确定。。。 但是试试这个:

float **f[4];
    for(int i = 0; i < 4; i++){
        f[i] = (float**)malloc(sizeof(float**));
    }
    printf("%ld", sizeof(f));
float**f[4];
对于(int i=0;i<4;i++){
f[i]=(浮动**)malloc(大小浮动**);
}
printf(“%ld”,sizeof(f));

您可以创建一个helper类,它可以通过转换神奇地为您自动创建一个合适的对象

template <unsigned N = 0> struct NewAny;

template <unsigned N> struct NewAny {
    template <typename T>
    operator T * () const { return new T[N]; }
};

template <> struct NewAny<0> {
    template <typename T>
    operator T * () const { return new T; }
};

int main () {
    float (**x)[4] = NewAny<2>();
    delete[] x;
    x = NewAny<>();
    delete x;
}
在您的示例中:

float (**f)[4] = NewAny<2>();
for (int p = 0; p < 2; p++) {
    f[p] = NewAny<3>();
}
Vectorate<float[4], 2>::type f;
f.resize(2);
for(auto &ff : f) ff.resize(3);
Vectorate::type f;
f、 调整大小(2);
对于(自动&ff:f)ff.调整大小(3);
普通的旧声明(不要这样做):

有点麻烦,但您不再关心内存泄漏:

std::vector<std::vector<std::vector<float>>> f(2, std::vector<std::vector<float>>(3, std::vector<float>(4)));
// Use with f[0][1][2]

还有一些模板矩阵类(例如opencv中的模板矩阵类)通过提供重载()操作符来正确地实现这一点,这样您就可以访问对象,如
f(0,1,2)

首先引入typedefs,以使其更清楚地了解发生了什么。编写的代码很糟糕。请改用
std::vector
。只需使用
std::vector
。或者,如果必须动态分配,至少使用智能指针。首先查找
std::make_unique
。查看我对所问问题的答案感兴趣。我理解,一个人应该也不会使用此代码。目标是使用
new
而不是
malloc
。在发布答案时,你应该确定这一点。如果你不是,你应该考虑留下一个注释,链接到你认为可能是他们想要的代码示例。浮点*F(4);对于(inti=0;i<4;i++){f[i]=newfloat;}printf(“%ld”,f);非常感谢。但是有可能精确地执行浮动(**f)[4]=new…?语法让我感兴趣。不,恐怕不可能像你写的那样。左边的部分声明一个大小为4的数组,指针指向堆栈上的浮点指针。就像编写
char buf[3]
时一样,您不应该将堆分配的指针分配给此(
buf=new char[3]
是未定义的行为)您可以得到的越接近
float(**f)[4]={new float*[3],new float*[3],new float*[3],new float*[3]}
。然而,您仍然需要迭代数组来分配数组中的内部指针。很明显,如果维度是固定的,您可以执行
float f[2][3][4]
Ah,我发现我误解了float(**f)[4]的实际功能。我以为它是指向4个浮点数组的指针,但实际上它是指向浮点指针的4个指针数组。我这样说对吗?除了syntaxic sugar之外,应该避免使用第一个代码,因为它允许接受任何无效的声明(只需在NewAny()前面编写您想要的任何内容,编译器会很乐意为您创建)。例如,在您的例子中,编译器将分配一个2x
数组,数组为4 float**
,如果我正确理解最初的问题,这并不完全是您想要的。最后一个示例更清晰,但对于多维数组大小而言,它不是动态的(这可能很好)@xryl669
NewAny
new
一样安全。如果LHS是
T*
,RHS是
newt
。只需删除一个类似
float(*f)[4]=NewAny()
,代码仍将编译。与编译器将阻塞的
float*t=newfloat*[2]
不同。我同意,这是一个很微妙的缺陷。这不是批评,这很好。我的评论只是想让一个外部观察者明白,使用基于模板的转换操作符可以消除赋值两边类似类型的双重检查,这通常是用普通的新旧运算符完成的。这是一个巧妙而有力的把戏,但缺点也应该说出来。
Vectorate<float[4], 2>::type f;
f.resize(2);
for(auto &ff : f) ff.resize(3);
try
{
    float *** f = new float ** [2];
    for (size_t i = 0; i < 2; i++)
    {
       f[i] = new float * [3];
       for (size_t j = 0; j < 3; j++)
           f[i][j] = new float[4];
    }
} catch(const std::exception & e) { /* This is a pain to deal with to avoid any leak */ }

// Now you can access via f[0][1][2]
// delete[] in reverse order.
try 
{
    typedef float BigArray[3][4];
    BigArray * f = new BigArray[2];
} catch(const std::exception & e) { /* here it's simple */ }
// delete with delete[] f
std::vector<std::vector<std::vector<float>>> f(2, std::vector<std::vector<float>>(3, std::vector<float>(4)));
// Use with f[0][1][2]
int vectorElems = 4, columns = 3, rows = 2;
int rowStride = vectorElems * columns;  
float * f = new float[rows*columns*vectorElems];
// Access with stride:
f[0 * rowStride + 1 * vectorElems + 2] = 3.14f;

// Delete with delete[] f