malloc函数在C中执行动态内存分配,是标准库的一部分。有关malloc的用法,行为和实现的问题,请使用此标记。
我正在分析跨虚拟页面分配的效果,同时创建维度为 PageSize x PageSize 的二维数组。我的机器的页面大小是 4096。我有一个 4096 个整数指针的数组(co...
我猜malloc和goto的关系有问题。或者,我猜想这里发生了一些内存浪费或内存损坏。 希望有人能指出我确切的错误......
我很困惑为什么在将 list 设置为指向 tmp 指向的位置(list = tmp;)后,这段代码释放列表而不是 tmp // 使用动态大小的数组实现数字列表 #包括 我很困惑为什么在将 list 设置为指向 tmp 指向的位置后,此代码释放列表而不是 tmp (list = tmp;) // Implements a list of numbers with an array of dynamic size #include <stdio.h> #include <stdlib.h> int main(void) { // List of size 3 int *list = malloc(3 * sizeof(int)); if (list == NULL) { return 1; } // Initialize list of size 3 with numbers *list = 1; *(list + 1) = 2; *(list + 2) = 3; // List of size 4 int *tmp = malloc(4 * sizeof(int)); if (tmp == NULL) { free(list); return 1; } // Copy list of size 3 into list of size 4 for (int i = 0; i < 3; i++) { tmp[i] = list[i]; } // Add number to list of size 4 tmp[3] = 4; // Free list of size 3 free(list); // Remember list of size 4 list = tmp; // Print list for (int i = 0; i < 4; i++) { printf("%i\n", list[i]); } // Free list free(list); return 0; } 唯一重要的是,您使用与 free 接手时相同的 地址 来拨打 malloc。分配的内存与该地址相关联,而不是与指针变量名称相关联。 在第一个 free(list); 处,您释放了用 int *list = malloc(3 * sizeof(int)); 分配的第一个块。 list = tmp; 现在list和tmp都指向同一个位置,从这个malloc调用返回的地址:int *tmp = malloc(4 * sizeof(int)); 从那里我们可以执行free(list)或free(tmp),这并不重要,因为它们指向同一位置,并且这是从malloc(4 ...调用返回的原始地址。 在第二个free()之后,list和tmp都是“悬空指针”,它们指向不再可用的内存区域。因此,在调用 free 之后直接将指针设置为 NULL 通常是一个好习惯。
我正在开发一个 C 程序,需要为结构数组动态分配内存。我知道使用 malloc 有时会失败,返回 NULL。但是,我不确定最好的练习...
我使用了github上的umm_malloc库,这是一个适合嵌入式系统的动态内存分配库。我写了一个测试函数,但是报错。以下是我的测试功能...
如何在 Windows 上为 Java 应用程序使用 mimalloc (或 jemalloc )?
我们在 Windows 上有一个完全用 java(实际上是 kotlin)编写的应用程序。有了malloc,我们的申请进程好像一直在增长,并没有释放内存,而Heap也没有什么问题……
leetcode第46题中int** returnColumnSizes是什么(语言:c)
这个问题是基于leetcode问题46:排列。 为了方便起见,问题的副本: 给定一个由不同整数组成的数组 nums,返回所有可能的排列。你可以回来...
我用c语言编写了这个程序,用于打印字符串的内容。 但不要打印字符串! #包括 #包括 #包括 #定义 GROW_BY 10 int main(){ ...
如果 malloc() 返回有效指针,但将 errno 设置为非零怎么办?
在微软关于malloc()的文档中,有以下两条语句: 在“返回值”部分: malloc 返回一个指向已分配空间的 void 指针,如果存在则返回 NULL
我观察到在简单的 C++ 程序中使用 malloc 与 new 时总内存分配存在差异,如 Valgrind 报告的那样。下面是我的程序的两个版本以及对应的
我想为程序创建一个小补丁。我对C了解不多。 当我的函数 get_streamlink 返回缓冲区时,下一个代码无法通过 m3u8 url 获取视频。当函数返回静态时...
以下代码出现错误:“munmap_chunk():无效指针”
使用命令编译了以下代码片段:gcc -g -std=c99 src.c src.c: #包括 #包括 无效填充(int * arr,int len,int val){ 对于 (int i = 0; i <...
我有两个整数指针,a和b。我使用以下行: int* b = malloc(3 * sizeof(int)); 我希望调用 sizeof(b) 返回 3 * sizeof(int) ,等于 12,但事实并非如此,它
为了学习堆内存,我使用了以下代码。我在被调用函数(fn1)内使用了 malloc,出于某种原因,我决定不释放被调用函数(fn1)内的内存。我通过了
为什么我的 malloc 会导致 lubuntu 上的 netbeans 中出现源未找到错误 (malloc.c)?
我在lubuntu上使用netbeans8.0.1,我无法在调试环境中通过我的malloc实例。我刚刚到达我的构建树 malloc 函数,然后出现反汇编窗口,显示“!所以...
在 C 中,分配一个 3*sizeof(float) 的空间并创建一个大小为 3 的浮点数组,做的事情基本上是一样的吗?
我的问题是是否写下这一行: float* array = malloc(3*sizeof(float)); 相当于写:float array[3]; 如果没有,为什么? (我真的是 C 新手) 我注意到当我尝试操纵
手册页告诉了我很多,通过它我了解了很多“glibc”内存管理的背景知识。 但我还是很困惑。执行“malloc_trim(0)”(注意零...
在 C 中,memcpy() 不需要/不建议强制转换为 (void*),就像 malloc() 不需要一样?
我对从以下网站读到的有关 memcpy()(和 malloc())的内容感到有些困惑: http://www.cplusplus.com/reference/cstring/memcpy/ 在该页面中,以下两行显然是...
是否应该避免强制执行一次 malloc 调用的内存分配实践?
我想知道为与结构相关的所有数据分配内存是否是一个好的做法。因此,假设我们有以下结构,其目的是存储浮点数组的数组: #包括 我想知道为与结构相关的所有数据分配内存是否是一个好的做法。因此,假设我们有以下结构,其目的是存储浮点数组的数组: #include <stdlib.h> typedef struct Arrays { int n; int* l; double** data; } Arrays; 可以像这样初始化一个示例: Arrays* UsualInitialization(int n) { // Constructs an array A of length n containing the arrays A[i] = [1,2,...,i] Arrays* A = (Arrays*) malloc(sizeof(Arrays*)); A->n = n; A->l = (int*) malloc(n * sizeof(int)); A->data = (double**) malloc(n * sizeof(double*)); for (int i = 0; i < n; i++) { A->l[i] = i + 1; A->data[i] = (double*) malloc((i + 1) * sizeof(double)); for (int j = 0; j < i + 1; j++) A->data[i][j] = j + 1; } return A; } 每个指针都有一个对应的 malloc 调用。但我们也可以这样做: Arrays* BlockInitialization(int n) { // Constructs an array A of length n containing the arrays A[i] = [1,2,...,i] Arrays* A = (Arrays*) malloc(sizeof(Arrays) + n * sizeof(int) + n * sizeof(double*) + (n * (n+1) / 2) * sizeof(double) ); A->n = n; A->l = (int*) (A + 1); A->data = (double**) (A->l + n); A->data[0] = (double*) (A->data + n); for (int i = 0; i < n; i++) { A->l[i] = i + 1; for (int j = 0; j < i + 1; j++) A->data[i][j] = j + 1; if (i < n - 1) A->data[i+1] = A->data[i] + i + 1; } return A; } 这里有一个 malloc 调用,所有其他指针都是通过指针算术和转换从第一个调用获得的。我认为这在某些情况下可能会更有效,因为所有分配的内存都在一个块中。 那么,我想问:这种做法是否会导致未定义的行为?它会影响性能吗(在某些情况下)?是不是让代码变得更加晦涩难懂? 我在下面留下了一个 print 方法和一个 main 方法,表明两种初始化给出了相同的结果(至少在我的机器上)。 void PrintArrays(Arrays* A) { printf("Variable contains %d arrays: \n", A->n); for (int i = 0; i < A->n; i++) { printf("Array %d (of length %d): [", i, A->l[i]); for (int j = 0; j < A->l[i]; j++) { printf("%f", A->data[i][j]); if (j < A->l[i] - 1) printf(", "); } printf("] \n"); } } int main() { Arrays* A = BlockInitialization(10); PrintArrays(A); Arrays* B = UsualInitialization(10); PrintArrays(B); return 0; } 那么,我想问:这种做法是否会导致未定义的行为? 如果你做得正确就不会。 这里唯一明显的问题是,对于奇数 n,最终的指针和双打可能会错位。您需要使用 alignof 来计算连续成员之间需要多少填充。 它会影响性能吗(在某些情况下)? 是的,它可以在受益于缓存友好的内存布局的平台上使性能更好。 如果您丢失所有指针,展平二维数组并提供简单的访问器来获取/索引数组,可能会更好,因为即使看起来冗余的偏移量计算通常也比多个指针取消引用更快。 这会让代码变得更加晦涩吗? 是的,但是如果晦涩的位被封装在两个函数(分配器和释放器)中,你可以很好地注释它,彻底测试它,然后忘记它。
所以显然动态内存分配允许在运行时分配内存,而不是像静态内存分配那样在编译时分配内存。我也明白在 malloc.h 中使用这些函数...