使用malloc和free了解指针 [英] Understanding of pointers with malloc and free

查看:82
本文介绍了使用malloc和free了解指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C语言中,指针是一件非常棘手的事情.对于很多人来说,很难理解它,因此,为了更好地理解,我编写了以下代码:

Pointers are a really tricky thing in C. For a lot of people is hard to understand it, so for a good understanding I wrote following code:

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

int main(int argc, char *argv[])
{
    int *p; // pointer -> will be dynamic allocated
    int *a; // array -> will be dynamic allocated

    // print before allocate memory (1)
    printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
    printf("&a: %p\ta: %p\t*a: %d\n", &a, a, *a);
    printf("\n");

    // allocate memory (2)
    p = (int *)malloc(sizeof(int));
    a = (int *)malloc(sizeof(int) * 10);

    // print after allocate, but before give a value to poinetrs (3)
    printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
    printf("&a: %p\ta: %p\t*a: %d\n", &a, a, *a);
    printf("\n");

    // give a value to poinetrs (4)
    *p = 1;
    for (int i = 0; i < 10; i++) { a[i] = i; }

    // print after we gave a value to pointers (5)
    printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
    printf("&a: %p\ta: %p\t*a: ", &a, a);
    // because a is an array we must use a loop for print 
    for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
    printf("\n");
    printf("\n");

    // free pointers (6)
    free(p);
    free(a);

    // print pointers after free (7)
    printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
    printf("&a: %p\ta: %p\t*a: ", &a, a);
    // because a is an array we must use a loop for print 
    for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
    printf("\n");
    printf("\n");

    // try to change values after free (8)
    *p = 12;
    for (int i = 0; i < 10; i++) { a[i] = 3; }

    // print after (8)
    printf("&p: %p\tp: %p\t*p: %d\n", &p, p, *p);
    printf("&a: %p\ta: %p\t*a: ", &a, a);
    // because a is an array we must use a loop for print 
    for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
    printf("\n");
    printf("\n");

    return 0;
}

输出:

&p: 0xbfe5db64  p: 0xbfe5dc24   *p: -1075452506
&a: 0xbfe5db68  a: 0xbfe5dc2c   *a: -1075452502

&p: 0xbfe5db64  p: 0x8716008    *p: 0
&a: 0xbfe5db68  a: 0x8716018    *a: 0

&p: 0xbfe5db64  p: 0x8716008    *p: 1
&a: 0xbfe5db68  a: 0x8716018    *a: 0 1 2 3 4 5 6 7 8 9 

&p: 0xbfe5db64  p: 0x8716008    *p: 0
&a: 0xbfe5db68  a: 0x8716018    *a: 0 1 2 3 4 5 6 7 8 9 

&p: 0xbfe5db64  p: 0x8716008    *p: 12
&a: 0xbfe5db68  a: 0x8716018    *a: 3 3 3 3 3 3 3 3 3 3 

现在,问题和观察:

  1. 当我在为内存提供指针之前打印指针时,为什么指针具有一个随机值和一个指向它的随机地址以及为什么它不是NULL?

  1. When I print pointers before give memory for it, why pointer have a random value and a random address to point to it and why it isn't NULL?

使用malloc之后,我们可以看到指针指向更改的地址,其值为NULL,那么malloc的作用是什么?

After we use malloc, we can see the address where pointer points to changed and its value is NULL, so what malloc really does?

给它赋值并打印后,释放它并再次打印,但是数组的值和地址与后面相同,但整数不相同,为什么?那么免费到底有什么呢?

After we give a value to it and print it, we free it and print it again, but values and address are same as behind for array, but not for the integer, why? So what free really does?

释放空间后,我们可以继续更改array和integer的值,为什么释放空间后可能发生这种情况?我们不需要重用malloc吗?

After we freed space, we can continue to change values of array and integer, why is this possible after free space? We don't need to reuse malloc?

推荐答案

  1. 因为语言规范是这样说的.指针的值(即它指向的地址)是不确定的.它可以指向任何地方,就像int可以保存任何值一样.读取这些值(就像在前一个printf中使用*p*a一样)实际上是未定义的行为.

  1. Because the language specification says so. The value of the pointer (i.e. the address it points to) is indeterminate. It can point anywhere, just like an int could hold any value. Reading those values, (as you do with *p and *a in the first printfs) is actually undefined behaviour.

如果您希望它指向的数据是0,那是偶然的.分配的内存不必清零.例如,它可能是先前分配了malloc然后是free d的块的一部分(free不会使内存清零,请参见下面的第3点.)

If you mean the data it points to is 0, that is by chance. The memory allocated does not have to be zeroed out. For example, it could be part of a block previously allocated with malloc and then freed (free doesn't zero out the memory, see point 3. below.)

那也是偶然的.当您free内存时,它不会被清零,也不必立即使用.它可以一直存储旧值,直到将其用于其他用途(例如,由另一种分配使用)

That is also by chance. When you free the memory, it is not zeroed out, and it does not have to be used immediately. It can keep storing old values until it is used for something else (for instance, by another allocation)

这也是未定义的行为.您正在写入不再拥有的内存.什么都可能发生.该程序可能已崩溃.偶然地,看来您可以成功地写入数组,可能是因为该内存仍未被其他任何东西使用,这会导致更明显的运行时错误.

That is also undefined behaviour. You are writing to memory you no longer own. Anything can happen. The program could have crashed. By chance, it seems like you can successfully write to the array, probable because the memory is still not used by anything else that would cause a more apparent run time error.

这篇关于使用malloc和free了解指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆