C(std = c99)指向结构内存分配的指针

时间:2015-12-12 01:44:19

标签: c memory-management malloc c99 local-variables

所以,这工作正常...这意味着,没有编译器错误,似乎没有内存泄漏,它正在做我想要它做的事情。那说应该有用吗?当我去books_init我发送一个本地变量到收集,这是不是意味着当我回到主要它不应该工作? (或未定义的行为?)。另外,如果你说我必须使用malloc,我必须在之后免费吗? (评论清理)

/* pseudo struct Collection{
    size_t size, capacity;
    Volume *volumes;
} */

void collection_init(Collection *col, size_t capacity){
    col->size = 0;
    col->capacity = capacity;
    col->volumes = malloc(sizeof(Volume) * capacity);
}

void collection_resize(Collection *col, size_t capacity){
    Volume *v = realloc(col->volumes, capacity * sizeof(Volume));
    if(!v) return;
    col->capacity = capacity;
    col->volumes = v;
}

void collection_add(Collection *col, Volume *volume){
    if(col->size >= col->capacity)
        collection_resize(col, col->capacity * 2);
    col->volumes[col->size++] = *volume;
}

void collection_clean(Collection *col){
    //for(vol : col->vol) free(vol);
    //should I free every element or just volumes?
    free(col->volumes);
}

void books_init(Collection *col){
    for(int i = 0; i < 25; ++i){
        Volume v = {.swag = i};
        collection_add(col, &v);
    }
}    



int main(){
    Collection col;
    collection_init(&col, 10); 
    books_init(&col);
    for(int i = 0; i < col.size; ++i){
        printf("\tVol[%d].id = %d\n", i, col.volumes[i].swag);
    }
    collection_clean(&col);
    return 0;
}

感谢您的时间

1 个答案:

答案 0 :(得分:2)

<set-variable variableName="tempId" value="8000" doc:name="Variable" /> <expression-component doc:name="Expression"> <![CDATA[ temp1 = message.payload.getRootElement().selectNodes('//palns/*'); foreach (plan1 : temp1){ plan1.selectSingleNode('planid').text = flowVars.tempId; } ]]></expression-component>

中的这一行
books_init

创建一个名为Volume v = {.swag = i}; 的局部变量,其成员v已初始化为swag。然后将该变量的地址传递给i。这是允许的,因为collection_add仍在范围内。

v

中的这一行
collection_add

col->volumes[col->size++] = *volume; 结构的内容进行复制,并将该副本存储在Volume中分配的内存中。

collection_init返回后,collection_add中的变量v超出了范围,但这没关系,因为books_init的内容被复制并保存在v的内存中{1}}指向。

当程序结束时,col->volumes只需要

collection_clean

从内存中删除所有free(col->volumes); 个副本。

如果Volume失败,我会在您的程序中看到唯一的缺陷。在这种情况下,您仍然会写入realloc数组。这将导致缓冲区溢出和内存损坏。为避免这种情况,Volume函数应在执行复制之前验证collection_add函数是否成功。例如,您可以在执行复制之前再次检查collection_resize

TL; DR 只要col->capacity > col->size始终成功,您的代码就可以了。