C 中的动态二维数组分配

发布于 2024-09-15 08:25:53 字数 393 浏览 1 评论 0 原文

我应该如何在 C 中分配动态数组?目前,我编写了一个名为 malloc2D 的函数,如下所示:

void* malloc2D(size_t unitSize, uint firstCount, uint secondCount)
{
    void** pointer = malloc(sizeof(id) * firstCount);
    for (int i =0; i < firstCount; i ++){
        pointer[i] = malloc(unitSize * secondCount);
    }
    return pointer;
}

它工作正常,但我被告知它给单独的内存分配带来了很大的压力。最好或最传统的方法是什么?

How I should allocate dynamic arrays in C? Currently I have a function I wrote called malloc2D that looks like this:

void* malloc2D(size_t unitSize, uint firstCount, uint secondCount)
{
    void** pointer = malloc(sizeof(id) * firstCount);
    for (int i =0; i < firstCount; i ++){
        pointer[i] = malloc(unitSize * secondCount);
    }
    return pointer;
}

It works fine however I have been told that it puts a lot of strain on the memory allocating separately. What is the best or most conventional way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往日情怀 2024-09-22 08:25:53

您可以一次分配整个块:

int ** foo;

foo = malloc(sizeof(int*) * firstCount);
foo[0] = malloc(sizeof(int) * firstCount * secondCount);
for (int i=1; i<firstCount; i++)
{
    foo[i] = foo[0] + i * secondCount;
}

You could allocate the entire block at once:

int ** foo;

foo = malloc(sizeof(int*) * firstCount);
foo[0] = malloc(sizeof(int) * firstCount * secondCount);
for (int i=1; i<firstCount; i++)
{
    foo[i] = foo[0] + i * secondCount;
}
瑾兮 2024-09-22 08:25:53

我的建议是保留你所拥有的。

  1. 已经开发出来了。
  2. 已经测试过了。
  3. 它直观/可读,无需使用宏。
  4. 它是可扩展的。
  5. 尚未定量地确定瓶颈。

有时,在没有问题的情况下尝试优化可能会损害性能。你有没有针对你朋友的理论做过任何基准测试?

malloc 一个大块需要定位连续的地址空间,甚至可能导致 malloc 在您当前的方法成功时失败(地址空间碎片等)。

当我说你当前的实现是可扩展的时,我的意思是调整大小是微不足道的。如果您分配了 [100][3],后来意识到您需要 [100][4],那么您需要做的就是 100 个非常小重新分配,可能不会更改地址。但是,如果宏方法需要调整大小,则需要重新分配可能不连续存在的整个块。更糟糕的是,由于数学方法发生了变化,数据不再位于宏可以访问的正确位置,因此您将需要一系列昂贵的 memmove

总而言之,我认为编写代码时始终牢记可读性、可维护性和易用性非常重要,并且只有在建立瓶颈后才进行优化。

My suggestion would be to keep what you have.

  1. It's already developed.
  2. It's tested.
  3. It's intuitive/readable without using a macro.
  4. It's extensible.
  5. No bottleneck has quantitatively been identified.

Sometimes trying to optimize when there is not a problem can hurt performance. Have you done any benchmarks against your friends theory?

mallocing a big chunk requires locating contiguous address space, and might even cause malloc to fail when your current method would succeed (address space fragmentation, etc).

When I said your current implementation is extensible, I mean it is trivial to resize. Should you allocate for a [100][3] and later realize you need a [100][4] then all you need to do is 100 very small reallocs, likely not changing addresses. However, should the macro method need resizing, you need to realloc the whole chunk which may not exist contiguously. Even worse, the data is no longer in the right place to be accessed by the macro because the math has changed, so you will need a series of expensive memmoves.

To generalize, I think it is important to always code with readability, maintainability, and ease of use in mind - and only optimize away from that after establishing a bottleneck.

客…行舟 2024-09-22 08:25:53

您可以像这样将数组分配为连续的块。假设您想要整数:

int (*arr)[secondCount] = malloc( sizeof(int[firstCount][secondCount]) );

您可以将其隐藏在一个宏后面,该宏将类型名作为宏参数,尽管代码很简单,实际上并不是必需的。

You can allocate the array as a contiguous bloc like this. Suppose you want ints:

int (*arr)[secondCount] = malloc( sizeof(int[firstCount][secondCount]) );

You could hide this behind a macro which takes the typename as a macro argument, although the code is simple enough that that is not really necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文