【问题标题】:Free first element of array释放数组的第一个元素
【发布时间】:2017-08-18 13:51:33
【问题描述】:

当我使用malloc 分配数组时,有没有办法只释放数组的第一个元素?

一个小例子:

#include <stdlib.h>
#include <string.h>

int main() {
    char * a = malloc(sizeof(char) * 8);
    strcpy(a, "foo bar");

    // How I would have to do this.
    char * b = malloc(sizeof(char) * 7);
    strcpy(b, a+1);


    free(a);
    free(b);
}

有没有办法只释放a 的第一个字符,以便我可以使用a+1 来使用字符串的其余部分?

【问题讨论】:

  • 不,你不能只释放一个字节的数组。您只能释放从malloc 返回的指针,该指针指向已分配数组的第一个字节,并且它还将释放所有已分配的字节数组。无论如何,您可以将其重新分配到您想要的大小,这可以是更多或更少的字节然后实际大小。
  • 更重要的是,为什么????
  • 看看this Dupe???
  • 您可以使用另一个指针,使用 char *b = a + 1; 及以后,您只需 free(a);
  • @WeatherVane 我知道。我只是想知道这是否可能。

标签: c arrays malloc free


【解决方案1】:

如果要删除a 的第一个字符,可以使用memmove() 将字符串中的剩余字符向左移动1,如果出现以下情况,可以使用realloc() 缩小分配想要的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char * a = malloc(sizeof(char) * 8);
    strcpy(a, "foo bar");

    puts(a);

    size_t rest = strlen(a);

    memmove(a, a+1, rest);

    /* If you must reallocate */
    char *temp = realloc(a, rest);
    if (temp == NULL) {
        perror("Unable to reallocate");
        exit(EXIT_FAILURE);
    }
    a = temp;

    puts(a);

    free(a);

    return 0;
}

更新

@chux 在the comments 中制作了几个good points

首先,与其在realloc() 中出现故障退出,不如直接继续而不将temp 重新分配给a;毕竟,a 确实指向了预期的字符串,分配的内存只会比需要的大一点。

其次,如果输入字符串为空,则rest 将为0。这会导致realloc(a, rest) 出现问题。一种解决方案是在修改a 指向的字符串之前检查rest == 0

以下是上述代码的稍微更通用的版本,其中包含了这些建议:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char *s = "foo bar";
    char *a = malloc(sizeof *a * (strlen(s) + 1));
    strcpy(a, s);

    puts(a);

    size_t rest = strlen(a);

    /* Don't do anything if a is an empty string */
    if (rest) {
        memmove(a, a+1, rest);

        /* If you must reallocate */
        char *temp = realloc(a, rest);
        if (temp) {
            a = temp;
        }
    }

    puts(a);

    free(a);

    return 0;
}

【讨论】:

  • 注意:在这种情况下,代码可以使用if (temp) { a = temp; } 来解决罕见的收缩分配失败,足以不更新a
  • 注意:rest == 0 时需要其他注意事项。在这种情况下,OP 的意图尚不清楚。
  • @chux——这些都是好点;我已在我的答案中添加了更新以纳入您的建议。
  • 带有评论的反对票可能会有所帮助;没有评论的投反对票(在三个月前的帖子上,不少于)只是神秘的。
【解决方案2】:

有没有办法只释放 a 的第一个字符

没有。您不能释放a 的第一个字符,因为它是char 类型。只有mallocfamily 函数返回的指针可以被释放。 你可以这样做。

char * a = malloc(sizeof(char) * 8);
strcpy(a, "foo bar");
char * b = malloc(strlen(a));
strcpy(b, a+1);
free(a);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    相关资源
    最近更新 更多