相关疑难解决方法(0)

为什么malloc + memset比calloc慢?

众所周知,它与初始化分配的内存calloc不同malloc.使用时calloc,内存设置为零.使用时malloc,内存不会被清除.

所以在日常工作中,我认为callocmalloc+ 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)

更换 …

c malloc

249
推荐指数
2
解决办法
5万
查看次数

malloc是否懒惰地为Linux(和其他平台)上的分配创建支持页面?

在Linux上,如果我去的话malloc(1024 * 1024 * 1024),malloc实际上做了什么?

我确定它为分配分配了一个虚拟地址(通过遍历空闲列表并在必要时创建新映射),但它实际上是否创建了1 GiB的交换页面?或者它mprotect是地址范围并在您实际触摸它们时创建页面mmap吗?

(我正在指定Linux,因为标准对这些细节没有提及,但我有兴趣知道其他平台也会这样做.)

linux malloc

71
推荐指数
5
解决办法
2万
查看次数

如何使用C从键盘读取字符串?

我想读取用户输入的字符串.我不知道字符串的长度.由于CI中没有字符串声明指针:

char * word;
Run Code Online (Sandbox Code Playgroud)

并用于scanf从键盘读取输入:

scanf("%s" , word) ;
Run Code Online (Sandbox Code Playgroud)

但是我遇到了分段错误.

当长度未知时,如何从C中读取键盘输入?

c string scanf

51
推荐指数
3
解决办法
25万
查看次数

在什么情况下malloc可以返回NULL?

它从来没有发生在我身上,而且我已经编程多年了.

有人能给我一个非平凡程序的例子,其中malloc实际上不起作用吗?

我不是在谈论内存耗尽:我正在寻找一个简单的情况,当你只分配一个由用户给出的绑定大小的内存块时,假设一个整数,导致malloc失败.

c malloc memory-management

28
推荐指数
6
解决办法
4万
查看次数

Windows 10中的malloc比Windows 7慢

我正在将我的应用程序从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字节时

  • Windows 7:0.391392毫秒
  • Windows 10:4.254411毫秒

当数据大小为100000000字节时

  • Windows 7:0.602178毫秒
  • Windows 10:38.713946毫秒

你有什么建议在Windows 10上改进吗?

我已经在Windows 10中尝试了以下内容,但遗憾的是性能没有得到改善.

  • 禁用超级抓取
  • 已禁用Ndu.sys
  • 磁盘清理

这是源代码.(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)

c performance windows-10

20
推荐指数
2
解决办法
1483
查看次数

什么是懒惰分配?

懒惰的对象分配是什么意思,它有什么用?

memory-management

18
推荐指数
1
解决办法
9505
查看次数

我们需要预先分配.但是MATLAB没有预先分配预分配?

在测试是否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

ram matlab memory-management

14
推荐指数
1
解决办法
335
查看次数

C11 stdatomic和calloc

我有一个包含原子场的结构:

#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?

c atomic c11

10
推荐指数
1
解决办法
370
查看次数

圆形正值半到2位小数

通常,舍入到小数点后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做同样的事情来实现我之前说的打印.

c number-formatting output-formatting

6
推荐指数
1
解决办法
2649
查看次数

malloc和heap:用于存储大小和链表信息的额外内存?

我有一个关于heap和的简单问题malloc:

当我们使用malloc如下方式分配一些内存空间时:

int *p;
p = (int*) malloc (10*sizeof(int));
Run Code Online (Sandbox Code Playgroud)

它实际上在堆中分配了10个单词.但是,我的问题是:

实际使用的内存空间真的是10个字吗?

或者还有其他额外的空间来存储内存大小的值?

或者,甚至,因为堆被构造为链接列表,是否有其他内存空间用于存储指向堆中列表的下一个节点的地址?

c c++ memory heap malloc

4
推荐指数
1
解决办法
685
查看次数