【问题标题】:Assign pointer to block reserved with malloc将指针分配给使用 malloc 保留的块
【发布时间】:2013-11-04 12:57:23
【问题描述】:

基于此答案:https://stackoverflow.com/a/19765782/1606345

#include <stdlib.h>

typedef struct {
    int *arr1;
    int *arr2;
} myStruct;

myStruct *allocMyStruct(int num)
{
    myStruct *p;

    if ((p = malloc(sizeof *p +
                 10 * sizeof *p->arr1 +
                 10 * num * sizeof *p->arr2)) != NULL)
    {
        p->arr1 = (int *)(p + 1);
        p->arr2 = p->arr1 + 10;
    }
    return p;
}

void initMyStruct(myStruct * a, int num)
{
    int i;

    for (i = 0; i < 10; i++) a->arr1[i] = 0;
    for (i = 0; i < 10 * num; i++) a->arr2[i] = -1;
}

int main (void)
{
    int num = 3;

    myStruct *a = allocMyStruct(num);
    initMyStruct(a, num);
    free(a);
    return 1;
}

p-&gt;arr1分配给(p + 1)的地址是否安全?

p->arr1 = (int *)(p + 1);

【问题讨论】:

  • 您可能会遇到内存对齐问题?
  • 在他的情况下,不,这段代码看起来“很好”
  • @art:如果它很常见,我认为它是p+1,结合演员表不会引起问题,具体取决于您编译此代码的平台?我的意思是:32 位指针占用 4 个字节,而 64 位指针需要 8 个字节......这就是我不确定的,无论如何......
  • p+1 给你一个指针,它有足够好的对齐来寻址一个 myStruct (在这种情况下)。在指向结构的指针的对齐限制低于任何结构成员的情况下,发明对齐要求介于困难和不可能之间。因此,在这种情况下,指针几乎不可能与 int 对齐,除非 int 具有比 int * 更高的对齐要求,我很难相信。可能有一些奇怪的架构会发生这种情况,但我不知道。理论上可以吗?也许。在实践中?很好。
  • @Art:我一直在挖掘。 p+1 确实不太可能造成麻烦,尽管没有真正的保证。 p+1 应该给出下一个指针,因此它会喊出 "shift" 4 或 8 个字节,具体取决于架构。虽然不能保证,但在 99.999... + IEEE 754 舍入误差 % 的机器上,这不会成为问题。

标签: c malloc


【解决方案1】:

您在考虑结构分配方面存在一个基本问题。 当你 malloc 一个结构时,你 malloc 那个结构的大小,你不 malloc 它将包含的数组,那些需要单独分配。为此,您的代码应该看起来更像:

myStruct *allocMyStruct(int num)
{
    myStruct *p = malloc( sizeof( myStruct ) );

    if( p != NULL )
    {
        p->arr1 = malloc( sizeof( int ) * 10 ); // p->arr1 now points to an array of 10 elements
        p->arr2 = malloc( sizeof( int ) * 10 * num ); // p->arr2 now points to an array of 10 * num elements
    }
    return p;
}

请记住,当您释放它时,您还需要单独释放数组,因此如果您的指针 myStruct 是 a:

free( a->arr1 );
free( a->arr2 );
free( a );

【讨论】:

  • OP 确实在这个 one 调用中为malloc() 分配了足够 内存。您可能想再看一遍。
  • OP 正在尝试优化,其中所有内存都被一次性分配,而不是使用单独分配。 arr1/arr2 指针被调整为指向该内存。这是一件非常有效的事情——但你必须关心对齐。
  • @nos:您在哪里看到对齐可能存在的问题?
  • @alk 在这种情况下可能没有 - 但在一般情况下你必须考虑它。
  • @JonathanMee:请问您指的是哪个“misbehaviour”?在 OP 的代码中确实有 一个 分配,它的返回值被传递给 free() - 这将工作得很好。
猜你喜欢
  • 2023-03-10
  • 2010-11-24
  • 2013-12-10
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
相关资源
最近更新 更多