释放指针是否释放了它所引用的内存?

时间:2014-09-09 07:36:08

标签: c

我目前正在通过Zed Shaw的“学习硬困难教程”教程,我试图了解堆栈中的内容以及以下示例中的堆上的内容,以及如何free()正在运作。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

/** our old friend die from ex17. */
void die(const char *message)
{
    if(errno) {
        perror(message);
    } else { 
        printf("ERROR: %s\n",message);
    }
    exit(1);
}

// a typedef creates a fake type, 
// in this case for a function pointer
typedef int (*compare_cb)(int a, int b);
// by declaring this pointer to a function
// we can use this like an int/char etc. in a function's arguments
/**
* A classic bubble sort function that uses the
* compare_cb to do the sorting.
*/
int *bubble_sort(int *numbers, int count, compare_cb cmp)
{
    int temp = 0;
    int i = 0;
    int j = 0;
    int *target = malloc(count * sizeof(int));

    if(!target) die("Memory error.");

    memcpy(target, numbers, count * sizeof(int));

    for(i = 0; i < count; i++) {
        for(j = 0; j < count - 1; j++){
            if(cmp(target[j], target[j+1]) > 0) {
                temp = target[j+1];
                target[j+1] = target[j];
                target[j] = temp;

            }
        }
    }
    return target;  // returns address of target(I think)
}                   // target will persist even after function 
                    // exit because we created on the heap (memcopy)
                    // so what happens if we run more than once?

int sorted_order(int a, int b)
{
    return a - b;
}

int reverse_order(int a, int b)
{
    return b - a;
}

int strange_order(int a, int b)
{
    if(a == 0 || b == 0) {
        return 0;
    } else {
        return a % b;
    }
}

/** 
 * used to test that we are sorting things correctly
 * by doing the sort and printing it out.
 */
void test_sorting(int *numbers, int count, compare_cb cmp)
{
    int i = 0;
    int *sorted = bubble_sort(numbers, count, cmp);

    if(!sorted) die("failed to sort as requested.");

    for(i = 0; i < count; i++){
        printf("%d ", sorted[i]);
    }
    printf("\n");

    free(sorted);
    sorted = NULL; 
}

int main(int argc, char *argv[])
{
    if(argc < 2) die("USAGE: ex18 4 3 1 5 6");

    int count = argc - 1;
    int i = 0;
    char **inputs = argv + 1;

    int *numbers = malloc(count * sizeof(int));
    if(!numbers) die("Memory error.");

    for(i = 0; i < count; i++) {
        numbers[i] = atoi(inputs[i]);
    }
    test_sorting(numbers, count, sorted_order);
    test_sorting(numbers, count, reverse_order);
    test_sorting(numbers, count, strange_order);

    free(numbers);
    numbers = NULL;

    return 0;
}

在函数bubble_sort中,在堆上创建一个int target数组。我的理解是,由于它在堆上,它将在函数退出后保持不变。

int *target = malloc(count * sizeof(int));
然后该函数返回target

return target;

我相信这意味着该函数返回target地址

稍后,在test_sorting中传递bubble_sort函数的结果

int *sorted = bubble_sort(numbers, count, cmp);

所以,如果我正确,指针sorted已设置为与target相同的地址

test_sorting *sorted末尾的

被释放,但*target指向的数据永远不会被释放。 但是当我在Valgrind运行程序时,我没有内存泄漏,所以这不可能。

我是对的,然后说,当我释放一个指针时,它指向的东西被释放了吗? 我想可能不是......我无法在网上找到任何参考资料,所以我假设我在上面的某个方面有误,但我无法看到。

4 个答案:

答案 0 :(得分:2)

你没有运行free来释放用于存储指针值的内存,而是释放指针引用的内存块,以及指针sortedtarget引用相同的内存块(在范围内)。当你free那个内存时,两个指针都不能合法地取消引用该块。

答案 1 :(得分:2)

  

释放指针是否释放了它所引用的内存?

是。引自:Usage of free

  

当我们想要释放先前由malloc()分配的内存块时,我们使用自由函数。此函数接受指向先前分配的内存块的char指针,并将其释放 - 即,将其添加到可以重新分配的可用内存块列表中。关于free()的几点说明:

     
      
  • 块的大小先前由malloc()存储在其内存映射中,这就是free()知道要释放多少字节的方式。
  •   
  • 未以任何方式清除或删除释放的内存。这就是为什么访问刚刚释放的内存不会导致崩溃的原因 - 其中的任何数据仍然与调用free()之前的数据相同。

  •   
  • free()函数无法使指向我们程序中可能仍然存在的给定内存块的指针无效。在我们调用free()之后,由我们(程序员)决定不尝试和取消引用仍然指向该内存块的指针。这样的指针被称为“悬挂指针”&#39; - 它们指向已经释放的内存,因此不应再次取消引用它们,除非它们被分配了不同(未释放)内存块的地址。

  •   

正如您所看到的,free()仅将内存块标记为空闲 - 没有执行此释放操作。

答案 2 :(得分:1)

指针本身在堆栈上分配,并且 - 正如您已经提到的 - 保存一个地址。您还可以按值返回指针并按值传递,除非您将指针传递给指针。 Malloc在某处分配内存并返回指向此位置的指针(地址)。如果您不希望此内存无法使用,则必须告诉系统您以后不再需要它。因此,您将先前分配的卡盘的地址(即指针)传递给空闲。这个调用实际上释放了指向的内存。当函数返回时,指针本身将超出范围。

答案 3 :(得分:0)

是的,已排序且目标将具有相同的地址 您可以通过打印两个值来看到这一点 在bubble_sort:printf(&#34;目标地址%X \ n&#34;,目标);
在test_sorting中:printf(&#34;已排序的地址%X \ n&#34;,已排序);

这些应该是相同的,所以返回地址,然后释放。