2011-09-10 5 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 
using namespace std; 

int width = 100; 
int height = 100; 

float cam[] = {-1.1,-1.0,1.2}; 
float D[] = {0.2,0.2,-0.2}; 
float U[] = {0.0,1.0,0.0}; 

float* cross(float* v1,float* v2) 
{ 
    float el1[] = {(v1[1]*v2[2]-v1[2]*v2[1]),(v1[2]*v2[0]-v1[0]*v2[2]),(v1[0]*v2[1]-v1[1]*v2[0])}; 
    return el1; 
} 

float* neg3(float* v) 
{ 
    float arr[3]; 
    for(int i=0;i<3;i++) 
    arr[i] = 0.0-(v[i]); 

    return arr; 
} 

/* 

float* cam_space(float* p) 
{ 
    float* e1 = cross(D,U); 
    float* e2 = cross(D,cross(U,D)); 
    float* e3_n = D; 

    float ar[4]; 
    ar[0] = e1[0]*p[0]+e1[1]*p[1]+e1[2]*p[2]; 
    ar[1] = e2[0]*p[0]+e2[1]*p[1]+e2[2]*p[2]; 
    ar[2] = -(e3_n[0]*p[0]+e3_n[1]*p[1]+e3_n[2]*p[2]); 
    ar[3] = p[3]; 
    return ar; 
} 

*/ 
float* translate(float* p,float* v) 
{ 

    float arr1[3]; 
    for(int i=0;i<=2;i++) 
    arr1[i] = p[i] + v[i]; 

    return arr1; 
} 


int main() 
{ 
    float* poi; 
    poi = cam; //undo later 

    float* nc; 
    nc = neg3(cam); 
    cout<<" "<<nc[0]<<" "<<nc[1]<<" "<<nc[2]<<endl; 


    float arbit[3] = {0.1,0.1,0.1}; 

    float* temp1; 
    temp1 = translate(poi,arbit); 
    //float* temp2; 
    //temp2 = cam_space(temp); 

    cout<<" "<<nc[0]<<" "<<nc[1]<<" "<<nc[2]<<endl; 
    cout<<" "<<poi[0]<<" "<<poi[1]<<" "<<poi[2]<<endl; 


    cout<<" "<<temp1[0]<<" "<<temp1[1]<<" "<<temp1[2]<<endl; 
    return 0; 
} 

알다시피, 나는 nc을 두 번 출력하고 있습니다. 그러나 두 값이 다릅니다. 두 번째로 nc이 표시되면 실제로는 temp1 값을 표시하고 temp1은 실제로 가비지 값을 표시합니다. 도움이 되었습니까?C++ 포인터 및 배열

+0

, 그래서 헤더 제거하기 :

이를 생각해 보자. 또한 앞으로는 여기에 언급 된 추론 때문에 cstdlib와 cstdio를 사용할 수도 있습니다. http://stackoverflow.com/questions/2847729/whats-the-main-difference-between-stdlib-h-and-cstdlib-in- c/2847753 # 2847753 또한 전역 변수가 전역 상수 일 경우 해당 변수를 전역 상수로 표시하십시오. –

+0

다른 모든 사람들이 (모두에게 +1) 사실과 [배열은 사악하다는] (http://www.parashift.com/c++-faq-lite/containers.html). –

답변

5
float* translate(float* p,float* v) 
{ 

    float arr1[3]; 
    for(int i=0;i<=2;i++) 
    arr1[i] = p[i] + v[i]; 

    return arr1; 
}// arr1 ceases to exist from this point. 

로컬 변수 arr1의 참조를 반환합니다. 스택에 상주하며 함수 호출이 반환되면 할당이 해제됩니다. 그러나 당신은 쓰레기 값을 산출하는 참조를 가지고 있습니다. 대신 newnew[] arr1을 반환하십시오. 완료되면 delete[]을 기억하십시오.

+1

Mashesh가 옳습니다. 'translate (float *, float *)'함수의 _scope_ (중괄호) 안에'float [] arr1' 변수를 만들었 기 때문에 함수가 실행되는 동안에 만 변수가 존재합니다. 그 후에도 여전히 동일한 메모리 블록을 가리키고 있지만 'arr1'은 더 이상 저장되지 않습니다. 자세한 내용은 http://en.wikipedia.org/wiki/Scope_(programming)를 참조하십시오. – wchargin

+2

어떤 컴파일러를 사용하고 있습니까? @Arpit? 'g ++'여기에 도움이 될 것입니다 : '함수에서 'float * cross (float *, float *)': 경고 : 로컬 변수 'el1'의 주소가 반송 됨, 등 –

1

translate()은 (배열 유형에서 변환 된) 로컬 포인터를 반환합니다. 그래서 temp1은 무엇을 말하는지, 함수 뒤에는 존재하지 않습니다. translate()가 반환됩니다.

neg3()도 마찬가지입니다.

C++을 사용하는 경우 std::vector<float>은 이러한 모든 문제를 해결합니다.

이 쓸 수 : 당신이 float[3]를 사용하는 whereever

std::vector<float> translate(const std::vector<float> & p, const std::vector<float> & v) 
{ 
    std::vector<float> vf(3); 
    for(int i=0;i <3;i++) 
     vf[i] = p[i] + v[i]; 
    return vf; //semantically, it returns a copy of the local object. 
} 

은 마찬가지로, std::vector를 사용합니다. 그리고 전역 변수를 사용하지 마십시오.

1

오른쪽 및 가운데 왼쪽의 지역 변수에 대한 포인터를 반환합니다. 이러한 변수는 함수 본문의 끝에서 범위를 벗어나며 결과는 정의되지 않은 동작입니다.

template <unsigned int N> 
void modify_me(float (&arr)[N]) 
{ 
    static_assert(N == 3, "You're doing it wrong!"); // C++11 feature 
    arr[0] = /* ... */ 
} 

:

void modify_me(float arr[]) // or `modify_me(float * arr)`, same thing 
{ 
    arr[0] = 0.5; 
    arr[1] = -2.25; 
} 

int main() 
{ 
    float myarray[2]; 
    modify_me(myarray); // now myarray[0] == 0.5, etc. 

    // ... 
} 

당신이 C에있어 이후로는 ++, 당신도 템플릿 마법을 사용할 수

배열 수정 기능을 처리하는 좋은 방법은 매개 변수로 배열을 전달하는 것입니다 이제는 크기가 3 인 자동 배열이 아닌 다른 것으로 호출하려고하면 컴파일 타임 오류가 발생합니다.

1

로컬 변수에 포인터를 반환하는 대신 값을 반환해야합니다. 당신은 다음 stdlib 또는 표준 입출력 기능을 사용하지 않는

struct V3 { float data[3]; } 

V3 neg3(V3 v) 
{ 
    for(int i=0;i<3;i++) 
     v.data[i] = -v.data[i]; 
    return v; 
}