【问题标题】:Where to free In C Code在 C 代码中释放的位置
【发布时间】:2018-01-17 23:54:54
【问题描述】:

我有一个可用的 C 代码。它连接 2 个字符数组并打印出解决方案。
但是我这里有一个动态内存管理(malloc),现在必须释放它。
谁能告诉我在哪里免费?为什么?

char * stringcat(const char * str1, const char * str2) {
    int length_1 = strlength(str1);
    int length_2 = strlength(str2);
    int length = length_1 + length_2 + 1;

    char * newstr = malloc(sizeof(char) * length);

    for(int i=0; i < length; i++)
    {
        char charToCopy = '\0';
        if(i < length_1)
        {
            charToCopy = *(str1 + i);
        } else if(i < (length_1 + length_2)) {
            charToCopy = *(str2 + i - length_1);
        }

        *(newstr + i) = charToCopy;
    }

    return newstr;
}


int strlength(char *c) {
    int count = 0;
    while(*(c + count) != '\0') {
        count++;
    }
    return count;
}


int main() {

    char surname[] = "Simon";
    char lastname[] = "Arndt";

    printf("%s\n", stringcat(surname, lastname));

    return 0;
}

【问题讨论】:

标签: c arrays copy malloc


【解决方案1】:

通常你应该在不再需要它的时候释放内存。为此,您应该将指针存储在某处。

int main() {
    char surname[] = "Simon";
    char lastname[] = "Arndt";
    char *res;

    res = stringcat(surname, lastname); // first store it
    if(res == NULL)
    {
        fprintf(stderr, "error");
        return 1;
    }

    // then print it
    puts(res); // equivalent to printf("%s\n", res);


    free(res);

    return 0;
}

不要忘记 C 字符串是 \0 终止的,这意味着当你 为字符串动态分配内存,你应该至少分配 strlen(string) + 1:

char * newstr = malloc(length + 1);

if(newstr == NULL)
    return NULL;

如果是字符串,则不需要sizeof(char),因为它总是一个。

对于其他类型,避免使用sizeof(&lt;type&gt;),容易出错。 而是这样做:

int *arr = malloc(10 * sizeof *arr);

sizeof *arr 将始终返回正确的字节数。

编辑

您应该始终检查malloc 不会返回NULL。当然,对于一个 像这样的简单程序,你可以跳过它。但在一个更大的项目中,你 绝对应该检查一下。

【讨论】:

  • 谢谢。所以你最后推荐 null res 吗? "res = NULL;"
  • @jwdonahue 从技术上讲,不能保证指针的大小应该相同,但实际上它们是相同的。 sizeof *ptr 但是会返回正确的大小。见stackoverflow.com/questions/1241205/…
  • @SimonArndt 对我来说,这取决于。这样做有充分的理由,但在您的示例中没有意义,因为您的程序无论如何都会在该点结束。见stackoverflow.com/a/1025604/1480131
  • @jwdonahue 我没这么说。例如,如果 arr 是一个简单的指针,那么 sizeof arr != sizeof *arr (可能存在这样的类型,但通常不是这样)。
  • @Pablo,脑子放个屁。在您发布回复的同时,我删除了我的评论。今天我的 lesdyxia 搞砸了。
【解决方案2】:

您泄漏内存是因为您没有将stringcat 的结果分配给char *。这样做。然后free 在你之后print。或者(在一个简单的程序中,比如这里介绍的)不要担心,让mainexiting 为您解决问题。

char *name = stringcat(surname, lastname);
printf("%s\n", name);
free(name);

【讨论】:

  • 不担心免费? xdd
  • 但是打印后如何释放?
  • 像这样:free(stringcat(surname, lastname)); ?
  • @mariusz_latarnik01 在像 OP 程序这样的简单程序中,忘记free 并没有什么坏处,因为当进程消失时,操作系统将释放任何剩余的内存。然而,我确实认为那是不好的风格。对于较大的项目,您应该在不需要时释放内存。
  • @SimonArndt 如果你调用它两次,那么你就分配了两次内存。如果您按照您的建议free 它,那么您分配两个并释放一个。这是相同的内存泄漏(加上毫无意义的分配和空闲)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-25
相关资源
最近更新 更多