2011-09-10 4 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; 
} 

Comme vous pouvez le voir, je génère deux fois nc. Mais les deux valeurs diffèrent. La deuxième fois nc est affiché, il montre réellement la valeur temp1, et temp1 montre effectivement des valeurs de déchets. Une aide?C++ pointeurs et tableaux

+0

Vous n'utilisez pas stdlib ou fonctions stdio, donc se débarrasser des en-têtes. Toujours dans le futur Vous pouvez utiliser cstdlib et cstdio à la place du raisonnement mentionné ici http://stackoverflow.com/questions/2847729/whats-the-main-difference-between-stdlib-h-and-cstdlib-in- c/2847753 # 2847753 Aussi, si ces variables globales doivent être des constantes globales, marquez-les comme telles. –

+0

Ce que tout le monde a dit (+1 à tous) et le fait que [les tableaux sont mauvais] (http://www.parashift.com/c++-faq-lite/containers.html). –

Répondre

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. 

Vous retournez la référence d'une variable locale, arr1. Il réside sur la pile et est désaffecté lors du retour de l'appel de fonction. Mais vous avez une référence à ce qui vous donne des valeurs de déchets. Au lieu de newnew[] arr1 et le renvoyer. Rappelez-vous de delete[] quand vous avez terminé.

+1

Mashesh a raison. Vous avez créé la variable 'float [] arr1' dans la _scope_ (accolades) de la fonction' translate (float *, float *) ', de sorte que la variable n'existe que lorsque cette fonction est en cours d'exécution. Après cela, vous pointez toujours sur le même bloc de mémoire, mais 'arr1' n'est plus stocké là. Voir http://en.wikipedia.org/wiki/Scope_(programming) pour plus d'informations. – wchargin

+2

Quel compilateur utilisez-vous, @Arpit? 'g ++' vous aidera ici: 'En fonction 'float * croiser (float *, float *)': avertissement: adresse de la variable locale 'el1' retournée', etc. –

1

translate() renvoie un pointeur local (converti à partir du type de tableau). Donc ce que temp1 fait référence à, n'existe pas après la fonction translate() renvoie. Il en va de même pour neg3(). Si vous utilisez C++, std::vector<float> résoudra tous ces problèmes.

Vous pouvez écrire ceci:

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. 
} 

De même, utilisez std::vector whereever vous utilisez float[3]. Et n'utilisez pas de variables globales.

1

Vous renvoyez des pointeurs vers des variables locales situées à droite et au centre. Ces variables sont hors de portée à la fin du corps de la fonction et le résultat est un comportement indéfini.

Une belle façon de gérer les fonctions de modification de tableau est de passer le tableau en tant que paramètre:

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. 

    // ... 
} 

Puisque vous êtes en C++, vous pouvez même utiliser la magie du modèle:

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

Vous obtenez maintenant une erreur de compilation si vous essayez d'appeler ceci avec tout ce qui n'est pas un tableau automatique de taille 3.

1

Au lieu de renvoyer des pointeurs vers des variables locales, vous devez renvoyer des valeurs.

Considérez ceci:

struct V3 { float data[3]; } 

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