简体   繁体   English

使用C中的动态内存分配解决地址行为

[英]Address behaviour with dynamic memory allocation in C

I wrote the following two codes and their outputs are given respectively. 我编写了以下两个代码,并分别给出了它们的输出。

Code 1: 代码1:

#include<stdio.h>
int* allocate(int array, int value)
{
    int k[array];
    //int *k=(int *)malloc(array*sizeof(int));
    for(int i=0;i<array;i++)
    {
        k[i]=value;
        printf("%d ",k[i]);
    }
    printf("\n");
    return k;
}
int main(void)
{
    int *p=allocate(3,25);
    for(int i=0;i<3;i++)
        printf("%d ",p);
    return 0;
}

Output: 输出:

25 25 25
0 0 0

Code 2: 代码2:

#include<stdio.h>
int* allocate(int array, int value)
{
    //int k[array];
    int *k=(int *)malloc(array*sizeof(int));
    for(int i=0;i<array;i++)
    {
        k[i]=value;
        printf("%d ",k[i]);
    }
    printf("\n");
    return k;
}
int main(void)
{
    int *p=allocate(3,25);
    for(int i=0;i<3;i++)
        printf("%d ",p);
    return 0;
}

Output: 输出:

25 25 25
12329552 12329552 12329552

I understand that in the first code, the data is allocated in the stack, and it would be cleared by the compiler once the return statement is executed. 我知道在第一个代码中,数据是在堆栈中分配的,一旦执行return语句,编译器将清除它们。 But I'm just printing 'p' and not '*p'. 但是我只是打印'p'而不是'* p'。 Why it shows 0? 为什么显示0? After all, pointer *p is declared within the main(). 毕竟,指针* p在main()中声明。

Kindly explain in simple terms. 请简单地解释一下。 Thanks in advance. 提前致谢。

EDIT 1: I'm adding a new code to make my question clear. 编辑1:我正在添加一个新代码,以使我的问题清楚。 Code 3: 代码3:

#include<stdio.h>
int* allocateArray(int size, int value)
{
int arr[size];
for(int i=0; i<size; i++) {
arr[i] = value;
}
return arr;
}

int main(void)
{
    int* vector = allocateArray(5,45);
for(int i=0; i<5; i++) {
printf("%d\t", &vector[i]);
}
    return 0;
}

Output: 输出:

0 4 8 12 16

In the third code, I can't print vector[i] or *(vector+i). 在第三段代码中,我无法打印vector [i]或*(vector + i)。 The compiler terminates the program. 编译器终止程序。

The explanation of 0 and the pattern in the output of the third code is what all I need. 我只需要解释0和第三代码输出中的模式。

In your answer you explain that you understand that you are returning a pointer to an array in allocate that ceases to exist before the pointer is assigned to p in main , and are wondering why a null pointer appears to be returned instead of a 'realistic' stack pointer, for instance. 在您的答案中,您解释说,您了解到,您正在返回一个指向allocate数组的指针,该数组在allocate指针分配给main p之前就不存在了,并且想知道为什么会出现空指针而不是“现实”指针例如,堆栈指针。

Why is NULL allowed? 为什么允许使用NULL

As explained in the comments, your compiler also knows that the pointer will not be valid by the time it is examined, and so can return a null pointer because of the following rule: 如注释中所述,编译器还知道在检查该指针时该指针将无效,因此由于以下规则,它可以返回空指针:

From ISO/IEC 9899:2011 Section 6.2.4 : 根据ISO / IEC 9899:2011第6.2.4节
The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime. 当指针所指向的对象(或刚过去的对象)达到其生命周期的终点时,指针的值将变得不确定

By indeterminate, it means the value of such a pointer will be unspecified or potentially a trap representation (which causes undefined behavior if read by any operation), which means a null pointer would be fine to return, as well as a pointer to another existing object, a pointer to no object, and a pointer value that could cause crashes or unexpected behavior in your program. 通过不确定,这意味着该指针的值将是未指定的或潜在的陷阱表示形式 (如果通过任何操作读取,则将导致未定义的行为),这意味着可以返回空指针以及指向另一个现有指针的指针。对象,没有对象的指针以及可能导致程序崩溃或意外行为的指针值。

Why did the compiler pick NULL ? 为什么编译器选择NULL

As for why the compiler implementation decided on a null pointer, possibly because it's a choice which is unlikely to silently break your program. 至于为什么编译器实现决定使用null指针,可能是因为它是一个不可能悄无声息地中断程序的选择。 A compiler will not usually impact performance to save you from yourself, but here it is at full liberty to optimize much of the preceding function away and simply return a null pointer that in a typical hosted environment will cause an immediate segfault if it is dereferenced, rather than allowing for the possibility of overwriting other objects in memory by trying to use the 'allocated' array. 编译器通常不会影响性能,从而使您免于自己的烦恼,但是在这里,完全可以自由地优化前面的大部分功能,只需返回一个空指针,该指针在典型的托管环境中(如果被取消引用)将立即导致段错误,而不是通过尝试使用“已分配”数组来允许覆盖内存中的其他对象的可能性。

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

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