Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么自由函数在我的代码中不起作用?_C - Fatal编程技术网

C 为什么自由函数在我的代码中不起作用?

C 为什么自由函数在我的代码中不起作用?,c,C,我试图释放“b”数组的第一行,但编译器抛出错误“free():无效指针。已中止” #包括 #包括 无效ft_编辑(字符***选项卡) { **tab=“hel”; } 内部主(空) { 字符**b; b=(char**)malloc(sizeof(char*)*3); *b=(char*)malloc(3*sizeof(char)); *(b+1)=(char*)malloc(3*sizeof(char)); *b=“tab”; *(b+1)=“交咨会”; printf(“之前:%s\n”,*b

我试图释放“b”数组的第一行,但编译器抛出错误“free():无效指针。已中止”

#包括
#包括
无效ft_编辑(字符***选项卡)
{
**tab=“hel”;
}
内部主(空)
{
字符**b;
b=(char**)malloc(sizeof(char*)*3);
*b=(char*)malloc(3*sizeof(char));
*(b+1)=(char*)malloc(3*sizeof(char));
*b=“tab”;
*(b+1)=“交咨会”;
printf(“之前:%s\n”,*b);
编辑和编辑;
自由(b[0]);
printf(“在:%s\n之后,*b);
printf(“%s”,*(b+1));
返回0;
}

在使用字符串和指针时,您必须明确的一点是,您可以分配指针,而不是在不同指针之间显式复制内容。特别是当你说

*b = (char *)malloc(3 * sizeof(char));

*b = "tab";
坦率地说,你做错了。您正在覆盖malloc提供给您的动态分配指针(在过程中丢失),并将其替换为指向编译器分配字符串“tab”的有效但非动态分配的指针。当您稍后调用
free(b[0])
(相当于
free(*b)
)时,您传递给
free
的指针是非动态分配的指针,而不是从
malloc
获得的指针,正如我所说,您丢失了它。这就是为什么你会收到这样的抱怨。(它实际上来自C运行时库,而不是编译器。)

要执行您试图执行的操作,您必须复制字符串,而不是简单地分配指针。您还必须确保分配的区域足够大。(请记住,字符串“tab”的大小是四个,其中一个用于终止
\0
字符。)

这是一个更正的版本

void ft_edit(char ***tab)
{
    strcpy(**tab, "hel");
}

int main()
{
    char **b;

    b = malloc(sizeof(char *) * 3);
    b[0] = malloc(10);
    b[1] = malloc(10);
    b[2] = malloc(10);
    strcpy(b[0], "tab");
    strcpy(b[1], "tac");
    printf("Before: %s\n", b[0]);
    ft_edit(&b);
    printf("After: %s\n", b[0]);
    printf("%s\n", b[1]);

    free(b[0]);

    return 0;
}
我将调用移动到
free
的末尾,因为您不想在打印前释放
b[0]
。(尽管如此,实际上没有必要释放
b[0]
,但如果您确实想在退出前释放东西,您还需要释放
b[1]
b[2]
,最后释放
b


我还消除了对
malloc
的返回的一些不必要的强制转换,以及在传递给它的大小中用`sizeof(char)进行一些不必要的乘法。

可以在数组表示法和差分指针之间来回切换。为同一个变量选择一个,在这种情况下没有理由同时使用这两个变量。您可以使用
*b=“tab”覆盖
b[0]
中的值,所以
免费(b[0])
是未定义的行为。或者,换一种说法:
*b=“tab”
不是将数据存储在malloc的内存中,而是使指针指向一个常量字符串,并覆盖/丢弃
malloc()
返回给您的指针。(无论如何,
“tab”
需要4个字符来存储,而不是3个,因为NUL终止符;因此,即使您使用
strncpy()
或类似工具将内容正确复制到其中,
3*sizeof(char)
空间不够)。此外,即使
free()
工作正常,也无法保证“After:”行的打印内容,因为尝试访问空闲内存是未定义的行为。一个实现完全有权崩溃,或者外观上看不出它已经将内存释放回池中,供将来的
malloc()
s通过同一进程使用。请注意,被称为a并不是一种恭维。作为一种学习练习,使用三个指针(三星)可能有一定的价值。在生产代码中,它通常是一个红旗.Nit,可能是“编译器分配的字符串”->“字符串文字”,还有一个简短的说明,即在几乎所有系统上,字符串文字都驻留在只读内存中,并且在进行赋值时,
*b=“tab”将字符串文本的地址分配给指针
b
。(所有这些都是您正确解释他覆盖原始指针地址的位置的前奏)
void ft_edit(char ***tab)
{
    strcpy(**tab, "hel");
}

int main()
{
    char **b;

    b = malloc(sizeof(char *) * 3);
    b[0] = malloc(10);
    b[1] = malloc(10);
    b[2] = malloc(10);
    strcpy(b[0], "tab");
    strcpy(b[1], "tac");
    printf("Before: %s\n", b[0]);
    ft_edit(&b);
    printf("After: %s\n", b[0]);
    printf("%s\n", b[1]);

    free(b[0]);

    return 0;
}