找出分配的内存是不是被 C 中的 realloc() 函数释放

Posted

技术标签:

【中文标题】找出分配的内存是不是被 C 中的 realloc() 函数释放【英文标题】:Find out if the allocated memory was freed by the realloc() function in C找出分配的内存是否被 C 中的 realloc() 函数释放 【发布时间】:2022-01-06 03:30:32 【问题描述】:

我的主要内容的一部分

int* p = NULL;
p = malloc(sizof(int)*10); 
p = realloc(p, sizeof(int) * 5);
free(p);

有什么方法可以查明,在重新分配之后,指针 p 是否指向一个大小为 20 字节而不是 40 字节的内存块?

理想的情况是有一个函数,它将内存地址作为参数,并告诉它是分配的还是空闲的。有这样的功能吗?

另一个想法是检查分配内存的 realloc() 之前和之后的大小。但是我看不出 sizeof() 有什么帮助,因为我将如何识别内存块, sizeof() 发送变量的大小而不是内存块的大小。 sizeof(p) 会给我 8 个字节,因为 p 是一个指针,而 sizeof(*p) 是 4,因为 p 指向一个整数。 也许 sizeof() 或其他函数有特殊用途?

如果您想知道我为什么要问,请阅读更多... 如果我初始化我的 p 以保存/指向一个数组

for (int i = 0; i < 3 ; i++)
   p[i] = i;

我现在希望 p 只保留 0,1,2,所以我想将 p 从 sizeof(int)* 5 重新分配到 sizeof(int)*3。 但是假设我真的不知道是否应该重新分配 p,内存块是 20 个字节,但可能已经是 12 个字节,并且不需要 realloc()。我知道我可以以任何一种方式运行 realloc() 并且它不会受到伤害,所以也许这不是这个问题的一个很好的理由。但在较长的代码中,很容易忘记分配的内存量。

任何帮助将不胜感激。

PS 如果没有人回答,我将不得不从 valgrind 发送 0 个错误中得到满足。 毕竟,如果出现问题,例如写入 20 字节块的第 21、22、23 和 24 字节内存(例如:p[4] = 7)(因为 p = realloc(p, sizeof(int) * 5)) valgrind 发送“大小为 4 的无效写入”类型的错误,但要得到它,我需要在此内存中写入。这种验证方法让我想得到错误,因为如果我能准确预测错误,那么我就知道分配内存的实际大小。

【问题讨论】:

您可以随时跟踪分配的内存大小。如果您不知道它确实有多少条目,那么无论您是否想要/需要realloc 它,您怎么能安全地访问它?不,没有可移植的方法来仅从指针获取分配的内存大小。 realloc() 仅在分配发生时才返回有效指针。如果没有,您将收到一个 NULL 指针。如果您比较旧值和新值,可以确定旧块只是缩小还是分配了不同的块。 to get that I need to write in this memory. This method of verification makes me want to get errors 为什么您想要验证这一点?如果你执行malloc(20) 并且成功了,你知道你有 20 个字节,没有必要验证它。 测试系统功能是没有意义的,除非你怀疑它们的实现。但在那种情况下,你就迷路了。阅读分配函数的文档,然后测试你的代码。 “没错,我不能”。好吧,您对malloc/relloc 之后的大小有足够的了解,以便能够在此之后存储大小。我正是这个意思。在没有分配的情况下失败,或者在您知道大小至少是您要求的大小的情况下成功。之后,由您来跟踪该大小。之后要求从指针中获取大小是不明智的。 【参考方案1】:

有什么方法可以查明,在重新分配之后,指针 p 是否指向一个大小为 20 字节而不是 40 字节的内存块?

没有

这种验证方法让我想得到错误,因为如果我能准确预测错误,那么我就知道分配内存的实际大小。

对编译器和链接器都使用-fsanitize=address。在这里阅读更多:https://***.com/a/40215639/6699433

【讨论】:

【参考方案2】:

没有可移植的方法来检查它。

您需要自己保留尺寸信息。

typedef struct String

    size_t size;
    int data[];
data_type;


data_type *allocate(data_type *dt, size_t size)

    if(!dt || dt -> size != size)
    
        dt = realloc(dt, sizeof(*dt) + size * sizeof(dt -> data[0]));
        if(dt)
        
            dt -> size = size;
        
    
    return dt;

用法与realloc 相同。如果您传递 NULL 指针,它将为数据分配严格和空间。如果更改大小,请将结果保存在临时指针中并检查分配是否失败。如果请求的大小与实际分配的空间相同,它将什么也不做(因为不需要重新分配)

【讨论】:

以上是关于找出分配的内存是不是被 C 中的 realloc() 函数释放的主要内容,如果未能解决你的问题,请参考以下文章

C:malloc/calloc/realloc/alloca内存分配函数

内存动态分配之realloc(),malloc(),calloc()与new运算符

通过动态分配创建数组后,在C中通过realloc改变内存大小时出现问题

C语言复习之malloc和realloc(为字符串数组分配内存)

C内存分配

c++内存示例004realloc,释放,对齐分配