C++ 在c/c+中分配数组时,这些额外的代码行是否需要无bug+;?

C++ 在c/c+中分配数组时,这些额外的代码行是否需要无bug+;?,c++,c,pointers,memory-leaks,C++,C,Pointers,Memory Leaks,对于C/C++中的二维数组分配,非常常见的代码是: const int array_size = .. ; array = (int**) malloc(array_size); for (int c=0;c<array_size;c++) array[c] = (int*) malloc(other_size); const int数组_size=; 数组=(int**)malloc(数组大小); 对于(int c=0;c一般来说,如果检测到malloc失败,您唯一能做的就是e

对于C/C++中的二维数组分配,非常常见的代码是:

const int array_size = .. ;
array = (int**) malloc(array_size);
for (int c=0;c<array_size;c++)
    array[c] = (int*) malloc(other_size);
const int数组_size=;
数组=(int**)malloc(数组大小);

对于(int c=0;c一般来说,如果检测到
malloc
失败,您唯一能做的就是
exit()
。此时,您无法安全地执行任何有关内存分配或释放的操作

#include <string.h>

void* alloc_2d_array(size_t xDim, size_t yDim, size_t elementSize)
{
    size_t indexSize = sizeof(void*) * xDim;
    size_t dataSize = elementSize * yDim * xDim;
    size_t totalSize = indexSize + dataSize;
    void* ptr = calloc(1, totalSize);
    if (!ptr)
        return ptr;
    void** index = (void**)ptr;
    void** endIndex = index + xDim;
    char* data = (char*)ptr + indexSize;
    do {
        *index = *data;
        data += elementSize;
    } while (++index < endIndex);
    return ptr;
}

int main()
{
    int** ptr = (int**)alloc_2d_array(3, 7, sizeof(int));
    for (size_t x = 0; x < 3; ++x) {
        for (size_t y = 0; y < 7; ++y) {
            ptr[x][y] = (10 * (x+1)) + (y + 1);
        }
    }
    free(ptr);
    return 0;
}

唯一的例外是,如果您在嵌入式环境中,不能选择退出。在这种情况下,您可能不应该首先使用
malloc

首先,您的代码格式不正确

array = (int*)
    array[c] = (int*)
这表明你是有意的

array = (int**)
    array[c] = (int*)
接下来,你声称这是“非常普遍的”,而事实上这只是“非常懒惰”

更好的解决方案是单一分配

#include <string.h>

void* alloc_2d_array(size_t xDim, size_t yDim, size_t elementSize)
{
    size_t indexSize = sizeof(void*) * xDim;
    size_t dataSize = elementSize * yDim * xDim;
    size_t totalSize = indexSize + dataSize;
    void* ptr = calloc(1, totalSize);
    if (!ptr)
        return ptr;
    void** index = (void**)ptr;
    void** endIndex = index + xDim;
    char* data = (char*)ptr + indexSize;
    do {
        *index = *data;
        data += elementSize;
    } while (++index < endIndex);
    return ptr;
}

int main()
{
    int** ptr = (int**)alloc_2d_array(3, 7, sizeof(int));
    for (size_t x = 0; x < 3; ++x) {
        for (size_t y = 0; y < 7; ++y) {
            ptr[x][y] = (10 * (x+1)) + (y + 1);
        }
    }
    free(ptr);
    return 0;
}
#包括
void*alloc_2d_数组(size_t xDim、size_t yDim、size_t elementSize)
{
size_t indexSize=sizeof(void*)*xDim;
大小\u t数据大小=元素大小*yDim*xDim;
大小=索引大小+数据大小;
void*ptr=calloc(1,总尺寸);
如果(!ptr)
返回ptr;
作废**指数=(作废**)ptr;
void**endIndex=index+xDim;
字符*数据=(字符*)ptr+索引大小;
做{
*指数=*数据;
数据+=元素大小;
}而(++指数

<>但是,假设语言是C,在C++中,上面的代码几乎完全失败。< / P>不,你不应该写第一个版本,也不应该写第二个版本。你应该使用<代码> STD::vector < /代码>。如果你不想谈论C++,并且想“在这里谈论原始指针或者关于C指针”C++代码应该从这个问题中删除。代码>…C/C++中非常常见的代码是< /C> > C++,它当然不是。Sam Varshavchik读我的最后一个注释PLZ,我说我知道STL容器方法,只询问使用<代码> null < />代码之间的原始数据,而不是使用<代码> >代码>使用C代码>oc
而不是
new
,使用原始指针而不是智能指针,并且不使用标准库设施,这显然不是C++。这些额外的代码行不会使您的程序没有bug,因为可能会有与这些额外代码行无关的bug。是的,谢谢,我认为这是非常可以接受的……只有一行分配和只有一个内核调用,它是有意义的,并且只有HH,但是!额外的计算:/@ HasDENHIA额外的计算是立即支付的时刻X>1。即使最小化分配数,仍然有内存泄漏。而且,您没有考虑对齐要求。最好有两个分配,一个用于指针和一个数据指针(作为单个块)。@Hasendhia:
malloc
(或
calloc
)不应该只在需要新页面时才对每个块进行内核调用。@Hasendhia:我的意思是
calloc
函数在C运行时库中,使用它的成本远不及内核调用(平均而言,
calloc
最终肯定会从内核获得内存,但它一次获得的内存量远远超过程序要求的内存量,然后根据需要分割内存块,并且它还重用
free()
d内存,而不涉及内核。重要的内核调用通常是
sbrk()
)一般来说,你可以打印一条错误消息,告诉用户释放一些内存,然后取消你试图做的任何事情。(但这在现代PC上通常不相关,因为你永远不会耗尽内存)