2014-09-12 165 views
0

想象我有以下的C函数:由C函数返回指针阵列

double * cross_product(double vec1[3], double vec2[3]) 
    { 
    double *outvec ; 

    *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1]; 
    *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2]; 
    *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0]; 
    return outvec ; 
} 

为什么程序在执行返回一个错误,而不是在编译阶段??

这其中也不起作用

double * cross_product_2(double vec1[3], double vec2[3]) 
    { 
    double var ; 
    double *outvec = &var; 

    *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1]; 
    *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2]; 
    *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0]; 
    return outvec ; 
// } 
+0

在第二个例子中,函数结束后,'var'超出了范围,并且返回的地址不再是有效的内存地址供您使用。还要注意在某个地方,你应该“释放”记忆。 – crashmstr 2014-09-12 19:00:12

回答

1

double *outvec包含垃圾,因为您尚未初始化或为其分配任何值
。 'outvec'上的任何操作都是对垃圾的操作,因此结果也包含垃圾。

校正在第二代码:

 REVISED CODE 
double * cross_product_2(double vec1[3], double vec2[3]) 
     { 
     double *outvec = NULL; // new change 
     outvec = (double *)malloc(sizeof(double)*3); //since you need space for 3 
                //doubles   


    /* 
      *(outvec + i) means, that the calculated value is to be stored at the ith 
      index of the address pointed to by the outvec pointer. That is how arrays 
       are indexed using pointers 
    */ 
     *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1]; 
     *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2]; 
     *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0]; 
     return outvec ; 
    // } 

说明:

您已经声明下面的变量 -
双* outvec;
“outvec”是用来存储结果将被存储的地址的指针。作为变量“outvec”的指针将指向结果将被存储的地址。 但是既然你没有指定那个地址是什么,所以“outvec”指向
某些随机地址是垃圾。 这就是为什么我们需要指定我们要在什么地址存储结果,并且为了这个
我们需要初始化或分配“outvec”变量和一些有效的地址。

+0

好吧,如果我添加这行双ss; \t double * outvec = &ss; – user3466199 2014-09-12 18:19:11

+0

@ user3466199 - 如果您的指针指向的地址为 有效,那么其余的地方应该落在原地,除非您做出其他 错误。 – 2014-09-12 18:36:43

+0

但指向一个双重和指向一个双数组有什么区别,为什么我需要声明一个数组不是一个简单的双,因为如果我在主程序上完成相同的工作,完全工作 – user3466199 2014-09-12 18:48:41

2

您尚未初始化outvec指针,所以你试图将数据写入到一个空(或垃圾)地址。试着为它指定一些内存,或者声明一个静态数组以便从你的函数返回。

例如

double *outvec = malloc(3 * sizeof(double)); 

由于在编译时编译器不计算outvec,所以会出现运行时错误。所以它不知道你将在运行时尝试访问什么地址。

+0

但是我必须在初始化任何指针之前填入任何其他值? – user3466199 2014-09-12 18:14:35

+0

@ user3466199 - 是..为了在某​​些操作中使用指针,您必须确保它包含有效地址(因为指针存储地址为 ),否则您只对一些随机内存位置执行 操作: 1.可能不可以是即使在你的流程环境中。 2.包含垃圾。 在这种情况下,如果你幸运的话,你会得到错误,如果没有,你会得到预期的答案。 – 2014-09-12 18:27:32

+0

请看看第二个代码 – user3466199 2014-09-12 18:31:15

3

你刚刚创建了指针“outvec”,但你不知道它指向的是哪里。我的意思是,你没有分配指针outvec将写入的内存。它只是试图在随机存储器空间上写入数据。
你需要“告诉”指针中应开始写入数据,并为您的工作预留该空间
正如乔尔说,尝试这样做,通过使用代码:

double *outvec = malloc(3 * sizeof(double)); 

对不起尽管我的英语不好......祝你好运!