日记 2019.12.12

1

malloc分配内存

1
double* lut = (double*) malloc(sizeof(double)*d.samples);

sizeof(double)=8

2

1
data = malloc(sizeof(d));

而我修改后,直接省去了data这个变量,因为看不到有什么用。(或许是,我修改后的代码,因为使用了智能指针,所以不需要data做某种辅助?)

PS:在HomeOfVapourSynthEvolution的Curve.cpp,能看到这种“成对”的模式,用malloccalloc来分配内存的变量都用free做了释放。相比之下,我自己该的代码,在新定义lut这个变量时,用了malloc,却没有用free,而是用delete去删除的。

delete不仅释放内存,而且会调用析构函数,而free不会调用析构函数。

Curve.cpp的代码

1
2
3
4
5
6
7
8
9
double (*matrix)[3] = reinterpret_cast<double(*)[3]>(calloc(n, sizeof(*matrix)));
double * h = reinterpret_cast<double *>(malloc((n - 1) * sizeof(*h)));
double * r = reinterpret_cast<double *>(calloc(n, sizeof(*r)));
if (!matrix || !h || !r)
throw std::string{ "malloc failure (matrix/h/r)" };

free(matrix);
free(h);
free(r);

我自己的代码

1
2
3
double* lut = reinterpret_cast<double*>(malloc(sizeof(double) * d->samples));

delete d->lut;

如知乎上所说,可以把delete看成做了两件事,一是free,另一是调用析构。

根据这篇博文测试的代码,得出“new 和 delete,malloc 和 free 只能匹配使用,不能混用”。

虽然这么说,但我想了一会,还是说不出,把我现有代码中的delete d->lut;改成free(d->lut)的理由…emm先不管了,我记得之前测试过这两种代码,似乎也没么(速度上的)区别…先这样吧…

3

1
2
free(d->lut);
free(d);

是不是要这么理解:freemalloc是成对出现的,因为用了两次malloc,所以就要有两次free

4

以下笔记照抄自菜鸟教程

“类声明只声明一个类的”尺寸和规格”,并不进行实际的内存分配”

“static 被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间”

“static 修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问”

5

malloc可分配的最大内存,看似去与size_t相关,到一些关于size_t的基础知识。

涉及到uintptr_t类型。

这篇博客中讲得清楚,uintptr_t是类型别名。

具体的定义如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned long int uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned int uintptr_t;
#endif

可以看到,unintptr_t是类型unsigned long int(64bit)和unsigned int(32bit)的别名。

PS:再回到修改代码的起点,看一下uint8_tuint16_t等的定义(来自stdint.h)

1
2
3
4
5
6
7
8
9
10
11
typedef unsigned char           uint8_t;  
typedef unsigned short int uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int uint64_t;
#else
__extension__
typedef unsigned long long int uint64_t;

由上可知,uint8_t对应char类型,长度为1字节,uint16_t对应short int类型,长度为2字节。

在实际代码中,二者分别对应8bit图像和16bit图像(或者说9~16bit图像)。

现在我需要回答一个问题,这样用不同类型/长度的变量去储存图像,究竟只是为了节省内存,还是必要之举?(我在测试用uint16_t类型变量储存8bit图像时,输出的图像是错误的,这样来看是必要的,但原理呢?为什么10bit图像就没事?->是否是对于10bit图像,有某种填0的机制?而8bit就会有内存越界的问题?)

6 数组与指针的区别