在C编程中,您可以将任何类型的指针作为参数传递给free,它如何知道要释放的已分配内存的大小?每当我传递指向某个函数的指针时,我也必须传递大小(即10个元素的数组需要接收10作为参数来知道数组的大小),但我不必将大小传递给自由功能.为什么不,并且我可以在我自己的函数中使用相同的技术来避免需要购买数组长度的额外变量?
我想知道如何malloc和free工作.
int main() {
unsigned char *p = (unsigned char*)malloc(4*sizeof(unsigned char));
memset(p,0,4);
strcpy((char*)p,"abcdabcd"); // **deliberately storing 8bytes**
cout << p;
free(p); // Obvious Crash, but I need how it works and why crash.
cout << p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果答案在记忆水平上是深入的,如果可能的话,我将非常感激.
可能重复:
free和malloc如何在C中工作?
考虑一种情况,我必须通过malloc分配大约20个字节的内存.对于malloc()的函数调用是否成功,20个字节是否应该在内存中连续可用或者是否可以分散?例如,在上面的例子中,如果有4个或5个块,每个10个字节,malloc会工作吗?或者这是特定于操作系统还是特定于编译器?
我最近一直试图理解严格别名的一个特定方面,我想我已经制作了尽可能小的有趣代码.(对我来说很有趣,就是!)
更新:根据目前为止的答案,很明显我需要澄清这个问题.从某个角度来看,这里的第一个列表是"明显"定义的行为.真正的问题是遵循这个逻辑到自定义分配器和自定义内存池.如果我malloc在开始时有一大块内存,然后编写我自己的my_malloc并且my_free使用那个单个大块,那么UB是不是因为它不使用官方free?
我会坚持使用C,有点随意.我得到的印象是更容易谈论,C标准更清晰一点.
int main() {
uint32_t *p32 = malloc(4);
*p32 = 0;
free(p32);
uint16_t *p16 = malloc(4);
p16[0] = 7;
p16[1] = 7;
free(p16);
}
Run Code Online (Sandbox Code Playgroud)
第二个可能malloc会返回与第一个相同的地址malloc(因为它free介于两者之间).这意味着它正在访问具有两种不同类型的相同内存,这违反了严格的别名.那么上面肯定是未定义的行为(UB)?
(为简单起见,让我们假设malloc总是成功.我可以添加检查返回值malloc,但这会使问题混乱)
如果不是UB,为什么?标准中是否有明确的例外,它说malloc和free(和calloc/ realloc/ ...)被允许"删除"与特定地址相关的类型,允许进一步访问在地址上"压印"一个新类型?
如果malloc/ free是特殊的,那么这是否意味着我不能合法地编写我自己的克隆行为的分配器malloc?我确信有很多项目都有自定义分配器 - 它们都是UB吗?
因此,如果我们决定必须定义这样的自定义分配器行为,则意味着严格别名规则本质上是"不正确的".我会更新它,说只要你不再使用旧类型的指针,就可以通过不同('new')类型的指针写入(不读取).如果确认所有编译器基本上都遵守了这个新规则,那么这个措辞可能会悄然改变.
我得到的印象是,gcc并且clang基本上尊重我的(积极的)重新解释.如果是这样,也许应该相应地编辑标准?关于 …
如果您尝试释放未使用的内存,会发生什么malloc/calloc?
这就是我的意思:
void main()
{
int temp = 0;
int *ptr = &temp;
free(ptr);
}
Run Code Online (Sandbox Code Playgroud)
我以为free()会返回一些错误代码,但free()没有返回值.
嗨,我有这个问题:为什么当我为malloc分配一个浮点数组的内存时,它会分配更多我要求的空间?例如,在这段代码中我试图分配一个十个"单元格"浮点数组,但如果我尝试访问其他单元格,则返回我没有段错误:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float *fk_array;
int main(int argc, char** argv){
fk_array = (float *) malloc(10 * sizeof(float));
int i;
fk_array[9] = 2.23;
fk_array[15] = 0.3;
for(i = 0; i<20 ; i++)
printf("%f\n",fk_array[i]);
free(fk_array);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
它回报我:
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
2.230000
0.000000
0.000000
0.000000
0.000000
0.000000
0.300000
0.000000
0.000000
0.000000
0.000000
Run Code Online (Sandbox Code Playgroud)
我错在哪里?
我试图向朋友解释免费是如何工作的,所以我想到了下面的代码示例来尝试解释它(复杂,我知道):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *stringPtr = NULL;
//Pass the size of the string in bytes to malloc
stringPtr = (char *)malloc(10 * sizeof(char));
strcpy(stringPtr, "A String. ");
printf("%s", stringPtr);
free(stringPtr);
printf("%s", stringPtr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
认为这段代码会释放堆上分配的内存,我假设如果我然后打印出分配给指针的字符串,它会做一些奇怪的事情或者崩溃程序,因为我认为它会尝试输出空值; 然而,当我运行它时,它最终只输出两次字符串.我想我会一步一步看看为什么,因为在我的脑海里,我想也许它将字符串复制到堆栈或其他东西然后指针指向一个新的内存地址,旧的内存毕竟被清理干净了(并不是说这种情况会有任何意义,但是,嘿,我不知道它会是什么),但当我逐步完成代码不仅没有释放内存,指针实际上仍然指向相同的内存地址,它具有相同的值.
当我调查它时,人们说你需要在调用free后指定一个空值,但我的问题是为什么?不应该释放只是解除分配该内存并将指针设置为null?保留价值的重点是什么?或者我只是不理解某事?
我是 C 新手。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void demo() {
char* s = malloc(10);
strcpy(s, "foo");
free(s);
}
int main()
{
demo();
}
Run Code Online (Sandbox Code Playgroud)
这个程序会泄漏几个字节的内存吗?