繁体   English   中英

C - memset 与免费

[英]C - memset vs free

我对调用 memset 时内存中实际发生的情况与调用 free 时发生的情况感到困惑。

例如,我有一个指向 char* 数组的指针 A

char** A = (char**)calloc(5, sizeof(char*));
int i;
for(i=0;i<5;i++)
{
  //filling
  A[i] = (char*)calloc(30, sizeof(char)); 
  scanf("%s", &A[i]);
}

现在我想重置它我的 char** 指针和它指向的所有元素完全为空

memset(A, 0, 5);

或者

free(A);

有什么不同?

我对 C 有点陌生,所以请用外行的话说谢谢

不同的是memset实际上是设置一块内存的值,而free返回内存供操作系统使用。

通过使用物理事物进行类比memset(beer, 0, 6)应用于六包啤酒的memset(beer, 0, 6)会将值 '0' 应用于数组beer所有六个成员,而free(beer)将相当于给把六包送给朋友。

memset函数将内存区域设置为请求的值。 请注意,您提供的大小是字节数

free函数释放分配的内存,因此不能再使用它。 调用free通常不会以任何方式修改内存。 在调用free后使用内存会导致未定义的行为

这两种方法都不正确,但有些互补。

memset会将缓冲区的内容设置为给定的值,在您的情况下为 0。 这将更改指针的值,这将导致您丢失对已分配缓冲区的引用(在每个A[i] )。

free(A)将释放 A 指向的缓冲区,但该缓冲区包含指针,并且它们指向的每个缓冲区都不会被释放。

简而言之 - memset 不会释放动态分配的缓冲区,并且 free 不会将其设置为零。

正确的方法是这样的:

for(i=0;i<5;i++)
{
    // complementary to
    // A[i] = (char*)calloc(30, sizeof(char)); 
    free(A[i]);
}
// complementary to
// char** A = (char**)calloc(5, sizeof(char*));
free(A);
A = NULL; // so no one gets confused...

free释放内存,这意味着 A 仍将指向相同的内存位置,这现在是无效的。

memset会将 A 当前指向的内存设置为您想要的任何内容。

memset更改内存地址处的内容。 它不会改变内存是否被分配/释放。

free不会改变内存地址的内容。 它释放内存块,使其可供程序回收和重用。 因此,指向该块的任何指针都会变得无效,并且尝试访问内存应该会导致段错误(“如果你很幸运”,正如我的教授所说的那样)。

当您知道将再次访问该地址的数据时,请使用memset 当您知道数据将不再被访问并且程序可能会回收该内存时,请使用free

memset() 方法只是用一个给定的字符替换 x 个内存字节,分配的内存由指针 *a 指向;

memset(a, 'a', x);

memset() 方法的原型是:

void* memset(void*, unsigned int, int);

memset()行为与strcpy()类似,但不同之处在于memcpy()按原样复制数据(字节),但strcpy复制格式化的字符串(因此执行时间比memcpy多)。

然而, free()方法只是释放内存空间并使其可被占用。

虽然其他答案解释了差异,但让我添加一个示例,当 memset() 和 free() 需要按特定顺序一起使用时:

如果 malloc 的内存区域用于存储任何需要擦除以防止其他人窥探它的关键/有价值的信息(比如一些与安全相关的东西,如管理密码或其他一些加密),你会想要首先擦除该内存区域中的内容,然后对其调用 free() 以将该区域的控制权交还给操作系统。

因此,就像 free() 是 malloc() 的对立面一样,memset(to zero)-then-free() 是 calloc() 的对立面。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM