What's the best way to initialize a dynamically allocated boolean 2d array?

huangapple go评论121阅读模式
英文:

What's the best way to initialize a dynamically allocated boolean 2d array?

问题

以下是翻译好的部分:

"只是试图(重新)学习C并在一些基本概念上遇到了问题。

我看了一下这个帖子:https://stackoverflow.com/questions/9215210/how-to-memset-an-array-of-bools。

根据那个帖子,似乎我可以像下面这样初始化一个布尔型的二维数组:

size_t size = sizeof(bool[4][3]);
bool (*ary)[4] = malloc(size);
memset(ary, false, size);

我看到这段代码的问题是它依赖于布尔值占用1字节,我认为这是与具体实现相关的。除此之外,根据我的手册页(Linux手册页项目),memset的第二个参数似乎是一个整数... 手册页上写着:“memset()函数用常量字节c填充s指向的内存区域的前n个字节。”这不是矛盾吗?如果c是一个整数,那么它不是一个字节长。

编辑1:请参见下面的Ouroborus评论关于最后一段。

所以经过思考,我想出了以下代码:

size_t size = sizeof(bool[4][3]);
bool (*ary)[4] = malloc(size);
const bool orig[4][3] = {
    {true, false, false},
    {false, true, true},
    {true, true, true},
    {false, false, false}
};
memcpy(ary, &orig, size);

这样我可以初始化我的内存不仅仅是0(false),还可以是任何我想要的值。我已经测试过了,但这根本不起作用。

所以我的问题是:我的代码有什么问题?更重要的是,应该如何做?

谢谢!"

英文:

Just trying to (re)learn C and struggling with some basic concepts.

I've took a look this thread: https://stackoverflow.com/questions/9215210/how-to-memset-an-array-of-bools.

According to that, it seems i may initialize a boolean 2d array like the following:

size_t size = sizeof(bool[4][3]);
bool (*ary)[4] = malloc(size);
memset(ary, false, size);

The problem i see with this code is that it depends on a boolean taking 1 byte, which i think is implementation dependant. Apart from that, the second parameter to memset according to my manual page (linux manpages project) seems to be an int... That manual page says "The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c". Isn't this contradictory? If c is an int then it's not a byte long.

EDIT1: See Ouroborus comment below about the last paragraph.

So after thinking a bit, i came up with the following code:

size_t size = sizeof(bool[4][3]);
bool (*ary)[4] = malloc(size);
const bool orig[4][3] = {
    {true, false, false},
    {false, true, true},
    {true, true, true},
    {false, false, false}
};
memcpy(ary, &orig, size);

This way i can initialize my memory not just with 0s (false), but with whatever i want. I've tested and this doesn't work at all.

So my question is: What's wrong with my code? And more important, what's the way to do this?

Thanks!

答案1

得分: 2

除了[4]之外,你的代码没有问题。不过,我建议使用以下方式:

bool (*ary)[3] = calloc(1, sizeof(bool[4][3]));
...
free(ary);

完成。一些注意事项:

  • 注意 [3],而不是 4。这是一个指向 bool [3] 数组的数组指针。之所以使用这种方式而不是 bool (*ary)[4][3],是因为如果我们去掉一个维度 - 这个维度总是最左边的一个 - 我们可以使用方便的 arr[i][j] 语法,这比 (*ary)[i][j] 更可读。
  • 请注意,calloc 会在分配过程中将整个数组清零。这几乎是 calloc 存在的唯一原因。
  • 如果您需要将数组初始化为除了 false 之外的其他值,那么确实可以使用 malloc + memcpy。但这可能会比仅仅调用一次 calloc 慢一点。然而,始终优先考虑代码的可读性而不是微优化。
英文:

Apart from the [4], there's nothing wrong with your code. I would however recommend to use this:

bool (*ary)[3] = calloc(1, sizeof(bool[4][3]));
...
free(ary);

Done. Some notes:

  • Note the [3], not a 4. This is an array pointer pointing at bool [3] arrays. The reason why we use this over bool (*ary)[4][3] is because if we discard one dimension - which always has to be the left-most one - we can use the handy arr[i][j] syntax, which is much more readable than (*ary)[i][j].
  • Note that calloc will zero out the whole array as part of the allocation process. That's pretty much the only reason why calloc exists in the first place.
  • If you need to init the array to something else than false then indeed use malloc + memcpy. But this will perhaps be a tiny bit slower than just one calloc call. Always prioritize code readability over micro-optimizations, however.

huangapple
  • 本文由 发表于 2023年8月10日 15:43:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76873587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定