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

查看:31
本文介绍了如何从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);

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

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天全站免登陆