将C函数返回的C指针释放给Fortran?

时间:2016-08-17 13:36:46

标签: c pointers memory fortran fortran-iso-c-binding

我有一个函数在C中返回一个看起来像这个

的char *指针
char * string_val (ARGS)
{
 char * svalue = cJSON_GetObjectItem(nml,var_name)->valuestring;
 return svalue;
}

在Fortran中,我将其分配给C指针(使用iso_c_binding)

type (c_ptr) :: C_String_ptr
...
C_String_ptr = string_val (ARGS)

这部分效果很好。 string_val函数被调用很多,我认为这会导致内存泄漏。我试图释放svalue指针的内存,但我刚刚遇到seg故障和内存转储。我现在有这样的事情:

     subroutine c_mem_free (cptr) bind(C,name="c_mem_free")
      use iso_c_binding
      type (c_ptr)   :: cptr   !< The C pointer whose memory needs to be freed
     end subroutine
...
 call c_mem_free(C_String_ptr)

,其中

 void c_mem_free (void** addrOfptr)
{
  free(*addrOfptr);    /* free the memory pointed to */
  *addrOfptr=NULL;     /* Nullify the pointer ;) */
}

追溯指向免费线路上的问题。我也尝试将更改cptr传递给值 type (c_ptr),VALUE :: cptr 并且在C方面有void*addrOfptrfree(addrOfptr),但这似乎也没有用。我也没有成功找到Fortran一侧svalue的内存位置。如果我使用像

这样的东西

write (6,'(z)')loc(C_String_ptr) write (6,'(z)')loc(c_loc(C_String_ptr))

这些都没有给我提供与打印svalue内存位置时相同的值。 在Fortran中返回后,如何释放指针svalue的内存?如何在Fortran中获取svalue内存的位置?

1 个答案:

答案 0 :(得分:1)

作为竖起大拇指的规则,你不应该免费使用&#34;在代码之外分配的内存。 cJSON也是如此。

解析对象后,树就会在内存中构建,您可以访问对象,其值,更改对象等。

完成文件处理后,您可以释放内存,调用 cJSON_Delete(root);

这个例程将为您处理一切。

如果要在使用对象/节点时释放对象/节点,也可以使用 cJSON_Delete(节点); 请记住,这个例程是&#34; reoursive&#34;。所以,如果你释放一个节点,它将释放所有的孩子和兄弟姐妹,正如你在这里的代码所看到的那样:

/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
    cJSON *next;
    while (c)
    {
        next=c->next;
        if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
        if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
        if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);
        cJSON_free(c);
        c=next;
    }
}

不要使用 cJSON_Free ,因为cJSON_Delete会处理所有事情,而cJSON_free必须在释放结构本身之前应用于结构的内部元素否则你会有内存泄漏。