简体   繁体   English

函数始终返回指向null的指针

[英]Function always returns pointer to null

Why does createArray function returns pointer to 0? 为什么createArray函数将指针返回0? I guess, that i should use malloc to fix it, but why? 我想我应该使用malloc来修复它,但是为什么呢?

   int *createArray(int size)
{
    int i;
    int arr[size];

    i = 0;
    while (i < size)
    {
        arr[i] = i;
        i++;
    }
    return arr;
}

int main()
{
    int *ar;
    printf("%i", (createArray(10)));
}

arr variable is allocated on the stack. arr变量分配在堆栈上。 When returning from your function the stack is freed. 从函数返回时,将释放堆栈。 The pointer you are returning will then point to an invalid memory location that may be set to null. 然后,您返回的指针将指向一个无效的内存位置,该位置可能设置为null。

When you return an array from a function, you're actually returning a pointer to the first element of the array. 从函数返回数组时,实际上是在返回指向数组第一个元素的指针。 And when a function returns, the memory used by its local variables are no longer valid. 当函数返回时,其局部变量使用的内存不再有效。

So you're returning a pointer to a variable that no longer exists. 因此,您将返回一个不再存在的变量的指针。 Using that pointer in any way invokes undefined behavior . 以任何方式使用该指针都将导致未定义的行为 In this particular case, the invalid address is able to be dereferenced and happens to contain the value 0, however there's no guarantee that behavior will be consistent when you make changes to your program. 在这种特殊情况下,无效地址可以被取消引用并恰好包含值0,但是不能保证在更改程序时行为将保持一致。

For this to work, you need to dynamically allocate memory. 为此,您需要动态分配内存。 Then it can be used though the lifetime of the program. 然后可以在程序的整个生命周期内使用它。

int *arr = malloc(sizeof(*arr) * size);

This also means you'll need to free this memory when you're done using it: 这也意味着您在使用free该内存后需要free该内存:

int *ar = createArray(10);
printf("%i", ar[0]);
free(ar);

The basic problem is that your function is returning the address of a local variable. 基本问题是您的函数正在返回局部变量的地址。 That local variable no longer exists once the function returns, so any pointer to it is invalid. 函数返回后,该局部变量将不再存在,因此指向它的任何指针都是无效的。

To correct some of the problems with your code, I added #include <stdio.h> to the top (required for printf ) and changed your printf call from 为了更正您的代码中的某些问题,我在顶部添加了#include <stdio.h>printf必需),并将您的printf调用从

printf("%i", (createArray(10)));

to

printf("%p\n", (void*)createArray(10));

When I compile with gcc and run the program, the output is: 当我用gcc编译并运行程序时,输出为:

(nil)

meaning that your function is returning a null pointer. 表示您的函数正在返回空指针。 (It's not a "pointer to null"; the pointer is null.) That's not what I would have expected; (这不是“指向null的指针”;该指针 null。)这不是我期望的; I expected a invalid garbage pointer value. 我期望一个无效的垃圾指针值。 (When I use tcc rather than gcc, I get 0x7fffd95a7140 .) (当我使用tcc而不是gcc时,我得到0x7fffd95a7140 。)

Apparently gcc recognizes that your code has undefined behavior, and replaces the return statement with the equivalent of return NULL; 显然,gcc识别出您的代码具有未定义的行为,并将return语句替换为return NULL;等效项return NULL; . This is a perfectly legitimate transformation (and it might prevent your program from doing something nasty with the invalid pointer, modifying memory that your program doesn't own). 这是一个完全合法的转换(它可能会阻止您的程序使用无效的指针进行令人讨厌的操作,从而修改程序不拥有的内存)。

Bottom line: Your program has undefined behavior, and you can't assume anything about what it will do. 底线:您的程序具有未定义的行为,并且您无法假设其将执行的操作。 And yes, allocating an array using malloc and returning the address of the allocated array is one way to fix it. 是的,使用malloc分配数组并返回分配的数组的地址是修复它的一种方法。

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

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