我试图找出如果我试图从中间"释放"指针会发生什么,请看下面的代码:
char *ptr = (char*)malloc(10*sizeof(char));
for (char i=0 ; i<10 ; ++i)
{
ptr[i] = i+10;
}
++ptr;
++ptr;
++ptr;
++ptr;
free(ptr);
Run Code Online (Sandbox Code Playgroud)
我收到一个崩溃,出现未处理的异常错误消息.我想了解为什么以及如何免费工作,这样我不仅知道如何使用它,而且还能够理解奇怪的错误和异常并更好地调试我的代码ץ
非常感谢
释放实例的函数struct Foo如下:
void DestroyFoo(Foo* foo)
{
if (foo) free(foo);
}
Run Code Online (Sandbox Code Playgroud)
我的一位同事建议如下:
void DestroyFoo(Foo** foo)
{
if (!(*foo)) return;
Foo *tmpFoo = *foo;
*foo = NULL; // prevents future concurrency problems
memset(tmpFoo, 0, sizeof(Foo)); // problems show up immediately if referred to free memory
free(tmpFoo);
}
Run Code Online (Sandbox Code Playgroud)
我看到NULL在释放后将指针设置为更好,但我不确定以下内容:
我们真的需要将指针分配给临时指针吗?它在并发性和共享内存方面有帮助吗?
将整个块设置为0以强制程序崩溃或至少输出具有显着差异的结果真的是一个好主意吗?
我有一个长期存在的应用程序,频繁的内存分配 - 释放.任何malloc实现都会将释放的内存返回给系统吗?
在这方面,什么是以下行为:
如果我有一个应用程序,其白天和夜晚的内存消耗可能非常不同(例如),我可以强制任何malloc将系统释放的内存吗?
如果没有这样的返回,释放的内存将被多次换出,但这样的内存只包含垃圾.
似乎有两个论点为什么人们应该NULL在释放它们之后设置指针.
简短:free()不小心召唤第二次,当它被设置为时,不会崩溃NULL.
几乎总是这掩盖了一个逻辑错误,因为没有理由free()第二次调用.让应用程序崩溃并能够修复它会更安全.
它不能保证崩溃,因为有时在同一地址分配新内存.
当有两个指向同一地址的指针时,主要发生双重自由.
逻辑错误也可能导致数据损坏.
短:malloc()除非释放指针设置为,否则访问释放的指针可能会导致数据损坏,如果在同一位置分配内存NULL
NULL如果偏移足够大(someStruct->lastMember,theArray[someBigNumber]),则无法保证在访问指针时程序崩溃.而不是崩溃将导致数据损坏.
将指针设置为NULL无法解决具有相同指针值的不同指针的问题.
随意扩展这个问题.
我知道将动态分配的数组的长度传递给操作它们的函数是一种常见的约定:
void initializeAndFree(int* anArray, size_t length);
int main(){
size_t arrayLength = 0;
scanf("%d", &arrayLength);
int* myArray = (int*)malloc(sizeof(int)*arrayLength);
initializeAndFree(myArray, arrayLength);
}
void initializeAndFree(int* anArray, size_t length){
int i = 0;
for (i = 0; i < length; i++) {
anArray[i] = 0;
}
free(anArray);
}
Run Code Online (Sandbox Code Playgroud)
但是如果我无法从指针中获取已分配内存的长度,那么free()当我提供的内容完全相同时,"自动"知道如何解除分配?作为一名C程序员,为什么我不能进入魔术?
从哪里free()获得免费(har-har)知识?
我一直在阅读有关malloc当您请求零大小的块时的行为的讨论.
我理解malloc(0)是实现定义的行为,它应该返回一个空指针,或者我仍然不应该访问的非空指针.(这是有道理的,因为不能保证它指向任何可用的内存.)
但是,如果获得这样一个不可访问的非空指针,我是否允许以free通常的方式传递给它?或者这是非法的,因为我得到的指针malloc(0)可能不指向实际分配的内存块?
具体而言,以下代码是否具有明确定义的行为:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* x = (int*) malloc(0);
if (x == NULL) {
printf("Got NULL\n");
return 0;
} else {
printf("Got nonnull %p\n", x);
}
free(x); // is calling `free` here okay?
}
Run Code Online (Sandbox Code Playgroud) 假设您有以下用于初始化多维数组的ANSI C代码:
int main()
{
int i, m = 5, n = 20;
int **a = malloc(m * sizeof(int *));
//Initialize the arrays
for (i = 0; i < m; i++) {
a[i]=malloc(n * sizeof(int));
}
//...do something with arrays
//How do I free the **a ?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用后**a,如何正确地从内存中释放它?
[更新](解决方案)
感谢Tim(以及其他人)的回答,我现在可以做这样的功能来从我的多维数组中释放内存:
void freeArray(int **a, int m) {
int i;
for (i = 0; i < m; ++i) {
free(a[i]);
}
free(a);
}
Run Code Online (Sandbox Code Playgroud) 直到今天,我仍然相信,调用free()内存空间会释放它以供进一步分配而无需任何其他修改.特别是,考虑到这个SO问题清楚地表明free()不会将内存归零.
但是,让我们考虑这段代码(test.c):
#include<stdlib.h>
#include<stdio.h>
int main()
{
int* pointer;
if (NULL == (pointer = malloc(sizeof(*pointer))))
return EXIT_FAILURE;
*pointer = 1337;
printf("Before free(): %p, %d\n", pointer, *pointer);
free(pointer);
printf("After free(): %p, %d\n", pointer, *pointer);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
编译(GCC和Clang):
gcc test.c -o test_gcc
clang test.c -o test_clang
Run Code Online (Sandbox Code Playgroud)
结果:
$ ./test_gcc
Before free(): 0x719010, 1337
After free(): 0x719010, 0
$ ./test_clang
Before free: 0x19d2010, 1337
After free: 0x19d2010, 0
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我一直生活在谎言中还是我误解了一些基本概念?还是有更好的解释?
一些技术信息:
Linux 4.0.1-1-ARCH x86_64
gcc version 4.9.2 …Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的C代码,用于构建如下所示的单链接列表,其中我使用malloc动态地为每个节点分配内存.在代码结束时,我想为每个分配的节点释放内存,想知道如何去做 - 如果我首先从头节点开始并释放它,那么指向后续节点的指针就会丢失并发生内存泄漏.
其他方式是从头节点开始并将节点指针保存在单独的指针或其他数组中,在存储节点指针时遍历列表直到尾指针,并且一旦到达尾节点,也将其存储到另一个数组指针并开始从该数组索引向后释放,直到头节点被释放.
这是实现我想要做的唯一方法吗?
如果我不想使用第二个缓冲区,我该怎么做呢.
#include "stdio.h"
#include "stdlib.h"
struct lnk_lst
{
int val;
struct lnk_lst * next;
};
typedef struct lnk_lst item;
main()
{
item * curr, * head;
int i,desired_value;
head = NULL;
for(i=1;i<=10;i++)
{
curr = (item *)malloc(sizeof(item));
curr->val = i;
curr->next = head;
head = curr;
}
curr = head;
while(curr) {
printf("%d\n", curr->val);
curr = curr->next;
}
//How to free the memory for the nodes in this list?
for(i=1;i<=10;i++)
{
free()//?? What logic here …Run Code Online (Sandbox Code Playgroud) 我在测试程序中观察到以下行为:
我正在malloc()为1 MB,然后free()之后sleep(10)。我做了五次。我正在观察top程序运行时的内存消耗。
一次free()-d,我期望程序的虚拟内存(VIRT)消耗将减少1 MB。但实际上并非如此。它保持稳定。这种现象的解释是什么?malloc()分配内存时是否做一些保留?