我有一个函数,它接收一个指向100个int的动态数组的指针。但是在此之前,我只有50个由malloc或calloc分配而不是100个。
有没有办法可以检查是否分配了任何元素(例如第79个),而不是想知道这个SIGSEGV实际意味着什么?
我的问题纯属理论,我没有实际的代码可以显示。
答案 0 :(得分:4)
不,指针不存储其大小。你可能最好将大小和指针存储在结构中并改为传递它:
typedef struct
{
size_t size;
int *ptr;
} my_data;
void myFunc(my_data *data)
{
size_t i;
for(i = 0; i < data->size; i++)
{
// data->ptr[i];
}
}
void myFunc2(my_data *data, size_t index)
{
if(index < data->size)
{
// memory location exists
}
}
答案 1 :(得分:1)
不,在代码中没有可移植且可靠的方法来检查它。
有一些工具 - 例如valgrind
- 可以帮助诊断某些类型的内存错误。
答案 2 :(得分:1)
不,没有。
这是您分解动态分析工具(例如 valgrind ),或使用保存有关其大小信息的真实容器。
答案 3 :(得分:1)
几年前我用了一个图书馆,我忘记了它的名字。使用它,您可以创建try-catch块并尝试访问未知数据,例如x [79]在try-block中,如果没有分配内存,则生成异常。
答案 4 :(得分:1)
嗯,你可以根据你的描述做这样的事情,给定一个数组并寻找一个索引(与“任何原始指针”略有不同)。有了更多的工作,甚至可以为任何指针做这样的事情。
malloc
函数必须存储有关分配量的信息。不幸的是,没有标准必须如何做到这一点。有些编译器会在分配的数据之前过度分配和存储大小。其他人可能会在地图中存储地址,而其他人可能会做其他事情,你不知道。
但是,大多数(所有?)C库和至少一个我知道的链接器明确支持重载/挂钩/替换分配功能。
例如,在GNU C库中,您可以设置__malloc_hook
。和GNU ld
允许你在__wrap_malloc
的链接器级别做这样的事情。
因此,您可以使用一个简单调用真实malloc
函数的函数来重载/挂钩free
和malloc
,并将信息存储在某处(例如,通过过度分配)并使用第一个词,或任何你喜欢的。)
然后编写一个带有基指针和索引的函数。该函数查看分配信息(现在您知道在哪里找到它!),并且可以轻松检查索引是否在范围内。这不适用于“任何指针”。
适用于“任何指针”的替代解决方案是编写一个满足来自不同场所的分配的分配器,而不是简单地包装真实的malloc
。来自同一竞技场的所有分配都具有相同的分配大小。给定任何指针,您只需迭代所有竞技场并查看该地址是否在竞技场的起始和结束地址内。
然而,人们通常应该非常确定已经分配了多少,这不应该是猜测,或随机运气,或者在运行时找出的东西。
此外,鉴于存在即用型内存调试器,我怀疑在应用程序方面做这样的事情是否值得投入时间。只需使用像valgrind这样的东西,根本不需要编写任何代码。