C 为什么自由函数在我的代码中不起作用?
我试图释放“b”数组的第一行,但编译器抛出错误“free():无效指针。已中止”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
#包括
#包括
无效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;
}