简体   繁体   English

C中的指针赋值,malloc()和free()

[英]Pointer Assignment, malloc() and free() in C

I'm very new in C programming and I was playing around with malloc() , free() and Pointer Assignment in order to get a better grasp of it. 我是C编程的新手,我正在玩malloc()free()和Pointer Assignment,以便更好地掌握它。

Here is my code: 这是我的代码:

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

#define SIZE    10

void
array_fill(int * const arr, size_t n)
{
    size_t i;
    for (i = 0; i < n; i++)
    arr[i] = i;
}

void
array_print(const int * const arr, size_t n)
{
    size_t i;
    for (i = 0; i < n; i++)
    printf("%d ", arr[i]);

    printf("\n");
}


int
main(int argc, char ** argv)
{
    int * p1, * p2;

    p1 = (int *) malloc(SIZE * sizeof(int));
    p2 = p1;

    array_fill(p1, SIZE);
    array_print(p1, SIZE);
    array_print(p2, SIZE);

    printf("\nFREE(p1)\n");
    free(p1);

    array_print(p2, SIZE);

    return (0);
}

Compiling it with gcc test.c -o test and running it with ./test : 使用gcc test.c -o test编译并使用./test运行它:

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 

FREE(p1)
0 0 2 3 4 5 6 7 8 9
  1. p2 = p1 , does it mean that p2 points to the same value as p1 ? p2 = p1 ,是否意味着p2指向与p1相同的值?
  2. After freeing p1 why I can still print p2 (Value of index 1 is different)? 释放p1为什么我仍然可以打印p2 (索引1的值不同)? Am I causing any memory leak or pointer dangling? 我是否导致任何内存泄漏或指针悬空?
  3. Is this normal to be able to print p2 even p1 is freed? 即使p1被释放,这是正常的能够打印p2吗?

1) Yes 1)是的

2) You are accessing freed memory which is a bad thing. 2)您正在访问释放的内存,这是一件坏事。

3) The behaviour is undefined. 3)行为未定义。 It could work, it could crash, it could print garbage, it could suck us all into a black hole (though unlikely) 它可以工作,它可能会崩溃,它可能会打印垃圾,它可能会把我们都吸进黑洞(虽然不太可能)

p2 = p1 , does it mean that p2 points to the same value as p1 ? p2 = p1 ,是否意味着p2指向与p1相同的值?

Yes, after the assignment both pointers point to the same region of memory. 是的,在赋值后,两个指针都指向同一个内存区域。

After freeing p1 why I can still print p2 (Value of index 1 is different)? 释放p1为什么我仍然可以打印p2 (索引1的值不同)? Am I causing any memory leak or pointer dangling? 我是否导致任何内存泄漏或指针悬空?

Yes, once you free p1 , the p2 pointer becomes dangling. 是的,一旦你释放p1p2指针就会变得晃来晃去。 Accessing anything through it is undefined behavior. 通过它访问任何内容都是未定义的行为。

Is this normal to be able to print p2 even p1 is freed? 即使p1被释放,这是正常的能够打印p2吗?

No, it is undefined behavior. 不,这是未定义的行为。

Don't let the fact that you see numbers that look like ones that you have previously confuse you: any resemblance with the numbers that were there before you called free is a complete coincidence. 不要让你看到的数字看起来像你之前曾混淆过你的数字:任何与你之前被称为free的数字相似的事情都是完全巧合。 Unfortunately, coincidences like that make problems with dangling pointers extremely hard to find. 不幸的是,像这样的巧合使悬垂指针的问题极难找到。 To aid with this problem, memory profiler programs take over the free -d region, and deliberately write some garbage values into it. 为了解决这个问题,内存分析器程序接管了free -d区域,并故意在其中写入一些垃圾值。 This makes detection faster, but it is not bulletproof. 这使得检测更快,但它不是防弹的。

  1. Yes, p2 points to same area as p1. 是的,p2指向与p1相同的区域。
  2. Apparently, memory is freed, but it wasn't reused yet (though, one value was already overwritten). 显然,内存已被释放,但它尚未被重用(但是,一个值已经被覆盖)。 After freeing memory, you're not supposed to access it via another pointer. 释放内存后,您不应该通过另一个指针访问它。
  3. It could lead to undefined behavior. 它可能导致未定义的行为。 In your case, it printed corrupted array. 在你的情况下,它打印出损坏的数组。 It also could've crashed with segmentation fault (if memory page no longer belonged to your application). 它也可能因分段错误(如果内存页不再属于您的应用程序)而崩溃。 Behavior could change depending on OS, compiler and other stuff, so it's better to avoid such practices. 行为可能会根据操作系统,编译器和其他内容而改变,因此最好避免这种做法。

1) The values stored in pointers are memory addresses. 1)存储在指针中的值是存储器地址。 Which means, two pointers with the same value points to the same address, which means the same memory region. 这意味着,具有相同值的两个指针指向相同的地址,这意味着相同的内存区域。

2) Freeing the pointer p1 only sets the value of p1 to NULL and says that the memory pointed to by p1 is free to use and it's no longer reserved. 2)解放了指针p1只设置的值p1NULL和说,指向的内存由p1是免费使用的,它不再保留。 But it doesn't erase the memory. 但它并没有抹去记忆。 It still holds it's value. 它仍然保持着它的价值。 But accessing it by another pointer that still has the address is an undefined behavior as it can be reserved for another thing. 但是通过另一个仍然具有地址的指针访问它是一个未定义的行为,因为它可以保留给另一个东西。

3) Yes it's normal as it's already explained in (2); 3)是的,这是正常的,因为它已在(2)中解释过; the memory region is not erased or set to 0 s and p2 still points to the address which means it still prints the same value 存储区域不被擦除或设置为0秒, p2仍指向地址,这意味着它仍然打印相同的值

Note that if the memory region is reserved by later by malloc , printing p2 may print another value if the memory region is modified. 注意,如果稍后由malloc保留存储器区域,则如果修改存储器区域,则打印p2可以打印另一个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM