1

我相信我这样做是对的,但我想确定一下。在一个程序中,我使用了两个指向函数返回的分配内存的指针。当我完成使用该内存free()时,我会使用相同的指针指向新分配的内存空间。这是我的程序,以举例说明我的意思(评论显示我的思考过程):

int main(void)
{
    char *data, *url;
        int i = 1;

    while(i)
    {
        printf("Enter URL: ");
        if(!(url = getstr())) return 1;                                  //url now points to allocated memory from getstr();
        if(strlen(url) <= 0) i = 0;
        if(data = readsocket(url, 80, "http")) printf("\n%s\n\n", data); //data now points to allocated memory from readsocket();
        else printf("\n\n");
        free(url);                                                       //free allocated memory that url points to url
        free(data);                                                      //free allocated memory that data points to data
    }
    return 0;
}

这是正确的,还是有更好的更普遍的首选方法?还是我完全做错了?

4

4 回答 4

5

假设您的函数getstrreadsocketmalloc 在内部分配内存,那么这非常好。

我唯一的建议是,在释放内存的同一范围内分配内存通常很有帮助,这通常有助于推断何时需要释放内存。

例如:

url = malloc(URL_MAX_LEN);
if (!url) return 1;
if (!getstr(url)) {
    free(url);
    return 1;
}
/* do something with url */
free(url);

如果您有很多对象和退出点,那么使用 goto 会很好。

object1 = malloc(OBJECT1_SIZE);
/* do work, if there's an error goto exit1 */
object2 = malloc(OBJECT2_SIZE);
/* do work, if there's an error goto exit2 */
object3 = malloc(OBJECT3_SIZE);
/* do work, if there's an error goto exit3 */
exit3:
free(object3);
exit2:
free(object2);
exit1:
free(object1);
return 1;

如果您的对象变得更复杂并且需要大量工作来创建和销毁,那么您可以包装 malloc 和 free,但至关重要的是,您将与 malloc/free 完全相同的规则应用于您的创建/销毁函数以避免泄漏。作为一个好的做法,你应该总是有一个销毁来匹配一个创建,即使它只是自由包装。这样就更难出错了。

struct x *create_x() {
    struct x *p = malloc(10);
    p->val1 = 7;
    return p;
}
void destroy_x(struct x *p) {
    free(p);
}
于 2012-08-28T13:36:31.123 回答
2

您的代码没有问题,但是您可以为 data 和 url 预先分配内存,并将它们作为参数传递给getstrreadsocket函数。这样会更有效率。

于 2012-08-28T13:35:59.383 回答
2

如果函数getstrreadsocket使用例如分配内存,malloc那么这就是你正在做的事情。

于 2012-08-28T13:36:14.483 回答
1

以下是我注意到的一些事情:

  1. i用于控制循环,但是当您设置 时i = 0,程序必须一直关闭大括号。我建议使用while (1)andbreak语句并摆脱i变量:

    while(1) {
        ...
        if (strlen(url) <= 0)
            break;
        ...
    }
    
  2. 您使用if (data = readsocket(url, 80, "http"))的在技术上并没有错,但它有点误导,因为有人可能会将其误认为是比较if (data == readsocket(url, 80, "http")。这几乎是 C 编程中的一种“模式”,通常像您在if (!url = getstr()))网上那样编写是一个好主意:

    if ((data = readsocket(url, 80, "http")) != NULL) ...
    

    或者

    if (!(data = readsocket(url, 80, "http"))) ...
    
  3. 这更像是一个“风格”相关,但最好在单独的行上写单独的语句,所以不要写

    if (!(url = getstr())) return 1
    

    反而

    if (!(url = getstr()))
        return 1;
    
  4. 至于释放内存,你做得很好

于 2012-08-28T13:49:51.630 回答