2016-01-23 169 views
0

我遇到了一种情况,我需要在函数中对矩阵进行一些数学运算(在编译时它的维数未知,因此我必须将其保存为指针),然后将其等同于到我作为参数传递给函数的指针。在C++中为指针指定指针

该代码每次都会引发分段错误。我这里有一个示例代码:

#include <iostream> 
using namespace std; 
void assign(int **a) 
{ 
    int **A = new int* [3]; 
    int i, j; 

    for(i = 0; i < 3; i++) 
    A[i] = new int[3]; 

    for(i = 0; i < 3; i++) 
    for(j = 0; j < 3; j++) 
     A[i][j] = 100; 

    a = A; /* equating the pointers */ 
} 

int main() 
{ 
    int **ptr; 
    assign(ptr); /* Passing my pointer into the function */ 
    cout << ptr[0][0] << endl; 
    return 0; 
} 

的代码是在C++中,它不是为我做的函数非void的返回类型的选项。我不想将矩阵保存在行/列主要的正常指针上 - 我需要知道为什么这不起作用。

+0

@Nidish你是否试过编写赋值给一个简单的'int'而不是'int **'的'assign'函数?以相同的方式写下来,并尝试检查赋值之前和之后的值是否有所不同 - http://denniskubes.com/2012/08/20/is-c-pass-by-value-or-reference/ –

回答

4

你的代码仔细看:

void assign(int** a) 
{ 
    // ... 
} 

int main() 
{ 
    int** ptr; 
    assign(ptr); 
} 

你传递a按值 - 调用assign(ptr)后,你会不会修改ptr自身函数体内的,而仅仅是一个的ptr副本。

通过引用以ptr代替:

void assign(int**& a) 
{ 
    // ... 
} 

其他可能的解决方案:

  1. 添加间接的另一个层次。

    void assign(int*** a) 
    { 
        // ... 
        *a = A; 
    } 
    
    int main() 
    { 
        int** ptr; 
        assign(&ptr); 
    } 
    
  2. assign返回。

    int** assign() 
    { 
        // ... 
        return A; 
    } 
    
    int main() 
    { 
        int** ptr; 
        ptr = assign(); 
    } 
    
+0

+1。我认为从'assign()'返回'A'是最简单也是最好的方法(不需要担心值/引用传递)。 – Michael

+1

没有必要将'a'全部传递给'assign'。你最后的例子应该是'int ** assign()'。 –

+0

@LightnessRacesinOrbit:哎呀,修好了。谢谢! –

0

想想究竟是什么在你的代码在内存方面情况。这里有一个例子,服用一些虚构的内存地址现在:

in main():         in assign(): 
ptr at 0x0100, value: garbage_ptr 
            call 
            -----> 
              a at 0x0200, value: garbage_ptr 
              [after some computation] 
              A at 0x0204, value: 0x0400 
              [after the line: a = A;] 
              a at 0x0200, value: 0x0400 
ptr at 0x0100, value: garbage_ptr 

你可以看到什么是如何以往任何时候都写入到0100的ptr地址。那是因为aassign()得到的值ptr;它不知道其中ptrptr仍然指向main()开始时的范围开始时的未触及(垃圾)值。

想,现在,这不是代码更改为:

... 
void assign(int ***a) 
{ 
    ... 
    *a = A; 
} 

int main() 
{ 
    int **ptr; 
    assign(&ptr); 
    .... 

上图现在变成:

in main():       in assign(): 
ptr at 0x0100, value: garbage_ptr 
&ptr rvalue, value: 0x0100 
            call 
            -----> 
              a at 0x0200, value: 0x0100 
              *a at 0x100, value: garbage_ptr 
              [after some computation] 
              A at 0x0204, value: 0x0400 
              [after the line: *a = A;] 
              a at 0x200, value: 0x0100 
              *a at 0x100, value: 0x0400 
            return 
            <----- 
ptr at 0x100, value: 0x0400 

这样,在0x0100值不得到改变,这是你想要什么。 (实际上,您应该在C++中使用这种类型的引用,但使用指针显示错误更容易。)