众所周知,它与初始化分配的内存calloc
不同malloc
.使用时calloc
,内存设置为零.使用时malloc
,内存不会被清除.
所以在日常工作中,我认为calloc
是malloc
+ memset
.顺便说一下,为了好玩,我为基准编写了以下代码.
结果令人困惑.
代码1:
#include<stdio.h>
#include<stdlib.h>
#define BLOCK_SIZE 1024*1024*256
int main()
{
int i=0;
char *buf[10];
while(i<10)
{
buf[i] = (char*)calloc(1,BLOCK_SIZE);
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
代码1的输出:
time ./a.out
**real 0m0.287s**
user 0m0.095s
sys 0m0.192s
Run Code Online (Sandbox Code Playgroud)
代码2:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BLOCK_SIZE 1024*1024*256
int main()
{
int i=0;
char *buf[10];
while(i<10)
{
buf[i] = (char*)malloc(BLOCK_SIZE);
memset(buf[i],'\0',BLOCK_SIZE);
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
代码2的输出:
time ./a.out
**real 0m2.693s**
user 0m0.973s
sys 0m1.721s
Run Code Online (Sandbox Code Playgroud)
更换 …
在Linux上,如果我去的话malloc(1024 * 1024 * 1024)
,malloc实际上做了什么?
我确定它为分配分配了一个虚拟地址(通过遍历空闲列表并在必要时创建新映射),但它实际上是否创建了1 GiB的交换页面?或者它mprotect
是地址范围并在您实际触摸它们时创建页面mmap
吗?
(我正在指定Linux,因为标准对这些细节没有提及,但我有兴趣知道其他平台也会这样做.)
我想读取用户输入的字符串.我不知道字符串的长度.由于CI中没有字符串声明指针:
char * word;
Run Code Online (Sandbox Code Playgroud)
并用于scanf
从键盘读取输入:
scanf("%s" , word) ;
Run Code Online (Sandbox Code Playgroud)
但是我遇到了分段错误.
当长度未知时,如何从C中读取键盘输入?
它从来没有发生在我身上,而且我已经编程多年了.
有人能给我一个非平凡程序的例子,其中malloc
实际上不起作用吗?
我不是在谈论内存耗尽:我正在寻找一个简单的情况,当你只分配一个由用户给出的绑定大小的内存块时,假设一个整数,导致malloc
失败.
我正在将我的应用程序从Windows 7迁移到Windows 10.
所有功能都没有任何更改,但执行时间比Windows 7
慢.似乎对象构造/破坏很慢.然后我创建了关于malloc()和free()的简单基准程序,如下所示.
for (int i = 0; i < 100; i++)
{
QueryPerformanceCounter(&gStart);
p = malloc(size);
free(p);
QueryPerformanceCounter(&gEnd);
printf("%d, %g\n", i, gEnd.QuadPart-gStart.QuadPart);
if (p == NULL)
printf("ERROR\n", size);
}
Run Code Online (Sandbox Code Playgroud)
我在同一台PC上的Windows 7和Windows 10中运行了这个程序.当数据大小为1,100,1000,10000,100000,1000000,10000000和100000000字节时,我测量了malloc()和free()性能.
在所有上述情况中,窗口10比窗口7慢.
特别是,当数据大小为10000000和100000000时,窗口10的速度超过十倍窗口7.
当数据大小为10000000字节时
当数据大小为100000000字节时
你有什么建议在Windows 10上改进吗?
我已经在Windows 10中尝试了以下内容,但遗憾的是性能没有得到改善.
这是源代码.(2月15日更新)
#include "stdafx.h"
#define START_TIME QueryPerformanceCounter(&gStart);
#define END_TIME QueryPerformanceCounter(&gEnd);
#define PRT_FMT(fmt, ...) printf(fmt, __VA_ARGS__);
#define PRT_TITLE(fmt, ...) printf(fmt, __VA_ARGS__); gTotal.QuadPart = 0;
#define PRT_RESULT printf(",%d", …
Run Code Online (Sandbox Code Playgroud) 在测试是否any()
短路时(确实如此!)我在预分配测试变量时发现了以下有趣的行为:
test=zeros(1e7,1);
>> tic;any(test);toc
Elapsed time is 2.444690 seconds.
>> test(2)=1;
>> tic;any(test);toc
Elapsed time is 0.000034 seconds.
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做:
test=ones(1e7,1);
test(1:end)=0;
tic;any(test);toc
Elapsed time is 0.642413 seconds.
>> test(2)=1;
>> tic;any(test);toc
Elapsed time is 0.000021 seconds.
Run Code Online (Sandbox Code Playgroud)
事实证明,这是因为变量在完全填充信息之前并不真正在RAM上,因此第一次测试需要更长时间,因为它需要分配它.我检查这个的方法是查看Windows任务管理器中使用的内存.
虽然这可能有些意义(不要在需要之前进行初始化),但让我更加困惑的是下面的测试,其中变量填充在for循环中,并且在某些时候执行被停止.
test=zeros(1e7,1);
for ii=1:1e7
test(ii)=1;
if ii==1e7/2
pause
end
end
Run Code Online (Sandbox Code Playgroud)
在检查MATLAB使用的内存时,我可以看到当停止时,它只使用了50%的test
所需内存(如果已满).这可以用不同的记忆百分比再现.
有趣的是,以下内容也没有分配整个矩阵.
test=zeros(1e7,1);
test(end)=1;
Run Code Online (Sandbox Code Playgroud)
我知道MATLAB不是动态分配和增加test
循环的大小,因为这会使结束迭代非常慢(由于需要高memcopys),并且它也会在我提出的最后一次测试中分配整个数组.所以我的问题是:
到底是怎么回事?
有人建议这可能与虚拟内存和物理内存有关,并且与操作系统看待内存的方式有关.不知道如何链接到这里提出的第一个测试.任何进一步的解释都是理想的.
赢得10 x64,MATLAB 2017a
我有一个包含原子场的结构:
#include <stdatomic.h>
struct s {
...
atomic_int a;
};
Run Code Online (Sandbox Code Playgroud)
该结构分配有calloc
:
struct s *p = calloc(1, sizeof(struct s));
Run Code Online (Sandbox Code Playgroud)
是否可以预期p->a
初始化为0?代码中有足够的障碍,因此初始化很弱,但是初始值是否保证为0?
通常,舍入到小数点后2位非常容易
printf("%.2lf",<variable>);
Run Code Online (Sandbox Code Playgroud)
但是,舍入系统通常会舍入到最近的偶数.例如,
2.554 -> 2.55
2.555 -> 2.56
2.565 -> 2.56
2.566 -> 2.57
Run Code Online (Sandbox Code Playgroud)
而我想要实现的是
2.555 -> 2.56
2.565 -> 2.57
Run Code Online (Sandbox Code Playgroud)
事实上,四舍五入在C中是可行的,但仅对于整数;
int a = (int)(b+0.5)
Run Code Online (Sandbox Code Playgroud)
所以,我要问的是如何在正值上用2位小数而不是Integer做同样的事情来实现我之前说的打印.
我有一个关于heap
和的简单问题malloc
:
当我们使用malloc
如下方式分配一些内存空间时:
int *p;
p = (int*) malloc (10*sizeof(int));
Run Code Online (Sandbox Code Playgroud)
它实际上在堆中分配了10个单词.但是,我的问题是:
实际使用的内存空间真的是10个字吗?
或者还有其他额外的空间来存储内存大小的值?
或者,甚至,因为堆被构造为链接列表,是否有其他内存空间用于存储指向堆中列表的下一个节点的地址?