如何从 C 中的指针获取数组的大小? [英] How can I get the size of an array from a pointer in C?

查看:37
本文介绍了如何从 C 中的指针获取数组的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经分配了一个大小为 nmystruct 的数组",如下所示:

I've allocated an "array" of mystruct of size n like this:

if (NULL == (p = calloc(sizeof(struct mystruct) * n,1))) {
 /* handle error */
}

后来,我只能访问p,而不再拥有n.有没有办法确定只给出指针 p 的数组的长度?

Later on, I only have access to p, and no longer have n. Is there a way to determine the length of the array given just the pointer p?

我认为它必须是可能的,因为 free(p) 就是这样做的.我知道 malloc() 会跟踪它分配了多少内存,这就是它知道长度的原因;也许有办法查询这些信息?比如……

I figure it must be possible, since free(p) does just that. I know malloc() keeps track of how much memory it has allocated, and that's why it knows the length; perhaps there is a way to query for this information? Something like...

int length = askMallocLibraryHowMuchMemoryWasAlloced(p) / sizeof(mystruct)

我知道我应该重新编写代码以便我知道 n,但如果可能的话我宁愿不这样做.有什么想法吗?

I know I should just rework the code so that I know n, but I'd rather not if possible. Any ideas?

推荐答案

不,如果不强烈依赖 malloc 的实现细节,是无法获得这些信息的.特别是,malloc 可能会分配比您请求更多的字节(例如,为了在特定内存架构中提高效率).重新设计代码会更好,以便明确地跟踪 n.另一种选择是至少同样多的重新设计和更危险的方法(鉴于它是非标准的,滥用指针的语义,并且对于那些追随你的人来说将是维护的噩梦):malloc 地址处的长度n,后跟数组.那么分配将是:

No, there is no way to get this information without depending strongly on the implementation details of malloc. In particular, malloc may allocate more bytes than you request (e.g. for efficiency in a particular memory architecture). It would be much better to redesign your code so that you keep track of n explicitly. The alternative is at least as much redesign and a much more dangerous approach (given that it's non-standard, abuses the semantics of pointers, and will be a maintenance nightmare for those that come after you): store the lengthn at the malloc'd address, followed by the array. Allocation would then be:

void *p = calloc(sizeof(struct mystruct) * n + sizeof(unsigned long int),1));
*((unsigned long int*)p) = n;

n 现在存储在 *((unsigned long int*)p) 并且数组的开始是现在

n is now stored at *((unsigned long int*)p) and the start of your array is now

void *arr = p+sizeof(unsigned long int);

只是为了扮演魔鬼的拥护者......我知道这些解决方案"都需要重新设计,但让我们发挥一下.当然,上面提出的解决方案只是一个(包装良好的)结构的 hacky 实现.你不妨定义:

Just to play devil's advocate... I know that these "solutions" all require redesigns, but let's play it out. Of course, the solution presented above is just a hacky implementation of a (well-packed) struct. You might as well define:

typedef struct { 
  unsigned int n;
  void *arr;
} arrInfo;

并传递 arrInfos 而不是原始指针.

and pass around arrInfos rather than raw pointers.

现在我们正在做饭.但只要你在重新设计,为什么要停在这里?您真正想要的是抽象数据类型 (ADT).算法和数据结构类的任何介绍性文本都可以做到.ADT 定义了数据类型的公共接口,但隐藏了该数据类型的实现.因此,公开的数组的 ADT 可能看起来像

Now we're cooking. But as long as you're redesigning, why stop here? What you really want is an abstract data type (ADT). Any introductory text for an algorithms and data structures class would do it. An ADT defines the public interface of a data type but hides the implementation of that data type. Thus, publicly an ADT for an array might look like

typedef void* arrayInfo;
(arrayInfo)newArrayInfo(unsignd int n, unsigned int itemSize);
(void)deleteArrayInfo(arrayInfo);
(unsigned int)arrayLength(arrayInfo);
(void*)arrayPtr(arrayInfo);
...

换句话说,ADT 是数据和行为封装的一种形式......换句话说,它与使用直接 C 语言的面向对象编程非常接近.除非你被困在一个平台上没有 C++ 编译器,您不妨全力以赴,只使用 STL std::vector.

In other words, an ADT is a form of data and behavior encapsulation... in other words, it's about as close as you can get to Object-Oriented Programming using straight C. Unless you're stuck on a platform that doesn't have a C++ compiler, you might as well go whole hog and just use an STL std::vector.

在那里,我们提出了一个关于 C 的简单问题,并最终选择了 C++.上帝帮助我们所有人.

There, we've taken a simple question about C and ended up at C++. God help us all.

这篇关于如何从 C 中的指针获取数组的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆