Can';c中不含t的malloc

Can';c中不含t的malloc,c,malloc,free,C,Malloc,Free,我是C的新手。我有以下代码。在free之后,第一个被释放的指针的长度为0,但不为null,第二个和第三个指针的长度仍然大于0。不确定这是否正常?谢谢 以下是输出: #包括 #包括 #包括 int main(){ char*str[3]; char*aa=“helloworld0”; char*bb=“helloworld1”; char*cc=“helloworld2”; str[0]=(char*)malloc(strlen(aa)+1); strcpy(str[0],aa); str[1]

我是C的新手。我有以下代码。在
free
之后,第一个被释放的指针的长度为0,但不为null,第二个和第三个指针的长度仍然大于0。不确定这是否正常?谢谢 以下是输出:

#包括
#包括
#包括
int main(){
char*str[3];
char*aa=“helloworld0”;
char*bb=“helloworld1”;
char*cc=“helloworld2”;
str[0]=(char*)malloc(strlen(aa)+1);
strcpy(str[0],aa);
str[1]=(char*)malloc(strlen(bb)+1);
strcpy(str[1],bb);
str[2]=(char*)malloc(strlen(cc)+1);
strcpy(str[2],cc);
字符**strr=str;
printf(“自由之前----长度:%ld,内容:%s,地址:%p\n”,
strlen(strr[1]),strr[1],strr[1]);
免费(strr[1]);
if(strr[1])printf(“非空1\n”);
printf(“自由后----长度:%ld,内容:%s,地址:%p\n\n”,
strlen(strr[1]),strr[1],strr[1]);
printf(“自由之前----长度:%ld,内容:%s,地址:%p\n”,
strlen(strr[0]),strr[0],strr[0]);
免费(strr[0]);
如果(strr[0]==NULL)printf(“非NULL 0\n”);
printf(“自由后----长度:%ld,内容:%s,地址:%p\n\n”,
strlen(strr[0]),strr[0],strr[0]);
printf(“自由之前----长度:%ld,内容:%s,地址:%p\n”,
strlen(strr[2]),strr[2],strr[2]);
免费(strr[2]);
if(strr[2])printf(“非空2\n”);
printf(“自由后----长度:%ld,内容:%s,地址:%p\n\n”,
strlen(strr[2]),strr[2],strr[2]);
}

将指针值传递到
free
后,该值的任何进一步使用都具有未定义的行为。即使
if(strr[1])
是无效的,并且没有有意义的结果,即使在实践中它通常反映出上次值有意义时,它是非空的

随后的操作更糟糕:

在这里,您不仅使用值
strr[1]
(指针),还传递一个函数,该函数将使用它访问该地址的对象(
strlen
)。这也有未定义的行为,它机械地访问不再属于程序的内存。这将导致编译器实现如何处理它可以看到的未定义的行为(注意:它甚至可以在让您走到这一步之前捕获,但它不必这么做),也可能取决于C库实现(
free
)如何处理您放弃给它的内存。有可能该地址将不再工作,访问该地址将出现故障并导致程序崩溃。也有可能它最终访问了现在属于实现的内存,可能存储了新的内容来跟踪它以便重用。也有可能产生完全不同的、意想不到的结果

在C语言中,你不能这么做。在
释放
malloc
获得的内存后,就完成了。您不能以任何方式处理指针或它以前指向的内存。没有办法“检查它是否被释放”。一旦它被释放,就这样了

许多程序员喜欢在释放指针对象所指向的内存后立即为其分配空指针值,以防止以后无意中尝试访问它:

strr[1] = NULL;    // or = 0;

释放内存实际上意味着释放内存中指定位置的所有权。其思想是,在释放它的过程中,它自身不能再从给定位置写入变量,而只能读取。为了在每次释放后使代码真正安全,应该将变量设置为NULL。它会将变量重定向到它指向的最后一个内存的sell之外,并使数据无法从它自己的变量读取。相反,指针将保留一个空值,该空值是指针的已知状态,没有所有权,因此可以使用。

free
表示您正在告诉系统:

我不再需要这个内存了,你可以随时使用这个内存

但系统不能保证何时清理和重新使用这些内存

下次当您访问此内存时,可能系统尚未清理它,或者它确实清理了。你只是不能确定它是否真的存在。这是一种未定义的行为


您应该添加
strr[1]=NULL以防止您意外访问已返回系统的空间。

欢迎使用SO!调用
free
后,您无法再访问数据,因此此程序的行为未定义。是否不能再注销给定位置,而只能读取?一旦释放了块,使用指针的读写都有未定义的行为。
printf("After free----Length:%ld,Content:%s,Address:%p\n\n",strlen(strr[1]),strr[1],strr[1]);
strr[1] = NULL;    // or = 0;