为什么printf()函数在C中破坏了指针地址?

时间:2017-09-17 11:01:28

标签: c++

我尝试了一个关于数组反转的例子:

#include <cstdio>
#include <cstdlib>

#define arr_size(dizi) (sizeof(dizi)/sizeof((dizi)[0]))

template<class F>
int* dizi_cevir(F (&dizi)){
    int boyut = arr_size(dizi);
    int donen[boyut];

    for (int i=0, k=boyut-1;i<boyut;i++,k--){
        donen[i] = dizi[k];
    }

    return donen;
}

int main() {
    int dizi[] = {1,2,3,4,5};
    printf("cevirmeden önce dizi(before reverse):\n");
    printf("%d %d %d %d %d\n",dizi[0],dizi[1],dizi[2],dizi[3],dizi[4]);

    int *pt = dizi_cevir(dizi);
    printf("cevirdikden sonra(after reverse):\n"); //problem is here
    printf("%i %i %i %i %i",*(pt),*(pt+1),*(pt+2),*(pt+3),*(pt+4));
    return 0;
}

但是我的输出是这样的:

cevirmeden önce dizi(before reverse): 
1 2 3 4 5 
cevirdikden sonra(after reverse): 
5 4 3 2 8
        ^==== must be 1,when i delete or move above printf() which include (after reverse) then it prints 1

这种情况的原因是什么?

1 个答案:

答案 0 :(得分:1)

template<class F>
int* dizi_cevir(F (&dizi)){
    int boyut = arr_size(dizi);
    int donen[boyut]; // <-- Stack allocated

    for (int i=0, k=boyut-1;i<boyut;i++,k--){
        donen[i] = dizi[k];
    }
    return donen; // And returned?!
}

很简单,你必须永远不要返回指向堆栈中进一步分配的变量的指针。在这种情况下,donen仅保证在执行dizi_cevir函数期间存在。

前4个元素只能偶然 ,因为printf没有触及它们。

函数dizi_cevir返回后,存储局部变量的内存可以在以后的任何函数调用中重新使用。