2017-09-17 48 views
-3

我试着约阵列的例子扭转这样的:为什么printf()函数在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 

什么是这种情况的原因是什么?

+6

'回道念;' - 你的程序调用*未定义行为*。只要函数返回,'donen'不再存在,但是你返回并取消引用一个悬挂指针。据透露,铛返回有关这个美丽的警告,这不应该被忽视:“main.cpp中:15:12:与局部变量‘多宁’相关的堆栈存储器的地址返回” – WhozCraig

+0

使用std :: vector的,而不是阵列。 std :: vector也有一个反向迭代器。 –

+0

@ manni66我不想使用C++的std库,我只是试着约指针数组的examle – natrollus

回答

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,其中本地变量存储是免费的任何未来的函数调用进行重新利用内存。

+5

决不一个*指针*返回到栈* –

+0

上被分配的变量i如何可以逆转与阵列指针或int数组[]? – natrollus

+1

@natrollus要么扭转它就地(这样就存储结果输入数组中),或者将需要在堆上分配结果阵列,而不是在堆栈。 – Ext3h