将动态创建的结构作为非指针对象返回

时间:2014-05-26 21:21:08

标签: c pointers malloc

//Smart pointer structure with built-in length and blocksize

typedef struct SMPTR_H_VAR
{
    UINT H_SMPTR_LEN;
    UINT H_SMPTR_BSZ;
} SMPTR_H_VAR;
typedef struct SMPTR
{
    void *MBLOC;
    SMPTR_H_VAR *shv;
    const UINT *const BLOCL;
    const UINT *const BLOCSZ;
} SMPTR;

//Smart pointer strucure 'constructor'
SMPTR *_SMPTRC(UINT var_sz, UINT var_num)
{
    /*            
    // SMPTR structure
    //
    // Memory block casted to void *
    // SMPTR_H_VAR structure
    // const UINT *const BLOCL variable, used as a reference length variable for the 'Memory block' above
    // const UINT *const BLOCSZ variable, used as a reference size variable, 'in bytes', for the size of the 'Memory block' above
    */

    //Creation and initialization is done dynamically, to prevent the rise of bad pointers.

    SMPTR *s = (SMPTR *)malloc(sizeof(SMPTR));
    SMPTR_H_VAR *shv = (SMPTR_H_VAR *)malloc(sizeof(SMPTR_H_VAR));

    //SMPTR_H_VAR variables are set through the SMPTR pointer
    s->shv;
    s->shv->H_SMPTR_LEN = var_num;
    s->shv->H_SMPTR_BSZ = var_sz * var_num;

    s->MBLOC = malloc(var_sz * var_num);
    s->BLOCL = &shv.H_SMPTR_LEN;
    s->BLOCSZ = &shv.H_SMPTR_BSZ;

    return s;
}

在此代码中,SMPTR作为指针返回,我想将此变量作为非指针返回。在这里,我在动态内存中创建一个结构,这样它就永远不会超出范围。这就是为什么到处都有很多指针。

2 个答案:

答案 0 :(得分:0)

从函数返回对象时看到的问题。

  1. 您在malloc中有三次致电_SMPTRC。了解哪些代码负责释放这些内存非常重要。否则,您的代码将泄漏内存。

  2. 调用函数将获得该对象的二进制副本。您将有两个SMPTR个对象指向动态分配的内存(shvMBLOC)。你必须找出一个释放他们指向的记忆的政策。

  3. 调用函数无法释放_SMPTRC中为s分配的内存。你有内存泄漏。通过使用s的对象而不是从malloc获取内存的指针,可以轻松解决此问题。

  4. 如果您确定哪个代码块负责为动态分配的内存付费,则可以解析它们。你只需要认识到这些问题。

答案 1 :(得分:0)

您的要求不兼容。如果按值返回结构,则返回值必须具有自动存储持续时间。您必须选择两个选项之一。

这两种设置都很好,但您还没有提供足够的详细信息来表明哪种方式对您的程序更好:

S foo(void)
{
     S s;
     s.field = 1;
     return s;
}

int main(void)
{
     S s = foo();
     printf("%d\n", s.field);
}

S *foo(void)
{
     S *s = malloc(sizeof *s);
     s->field = 1;
     return s;
}

int main(void)
{
     S *s_ptr = foo();
     printf("%d\n", s_ptr->field);
     free(s_ptr);
}