2013-07-21 3 views
1

основном то, что я пытаюсь сделать, это инициализировать мой массив внутри функции, но она возвращает ошибку сегментации:Инициализировать массив указателей на справочном C++

void func(int **a, int x, int y) { 
    a = new int*[x]; 

    for (int i=0; i<x; i++) 
     a[i] = new int[y]; 
} 

void main() { 
    int **a;  
    func(a, 2, 3); 
} 

Однако, если я инициализировать массив вне функции затем передать его, все отлично работает, я могу присвоить ему значения/напечатать их. То, с чем я борюсь, это передать ссылку на мой массив, поэтому мне не нужно запускать его вне функции.

void func(int **a, int x, int y) { 
    for (int i=0; i<x; i++) 
     a[i] = new int[y]; 
} 

void main() { 
    int x = 2; 
    int **a = new int*[x]; 
    func(a, x, 3); 
} 
+1

Я не верю, что код SEG-ошибки. Однако имейте в виду, что 'a' в' main' не изменяется. –

+8

Я теряю интерес во второй, я вижу 'int ** a', предположительно, код C++ – sehe

ответ

4

Что кусает вас здесь (и C++ 's) отсутствие C в передачи аргумента by-reference. a в main() отличается от a в func():

  1. a объявлен в main.
  2. a передается по значению (потому что нет другого способа) до func.
  3. a в func принадлежит.
  4. func возвращается. Его a уничтожен (утечка памяти), а main - a - остался неинициализированным.
  5. ???
  6. main пытается использовать a. Segfault!

Есть несколько возможных решений здесь:

  1. ли это классический путь C: передать указатель на значение. В этом случае параметр будет int ***a, который выглядит немного смешно, но что угодно.

    void func(int ***a, int x, int y) { 
        *a = new int*[x]; 
        for (int i=0; i<x; i++) 
         (*a)[i] = new int[y]; 
    } 
    
    int main(int argc, char **argv) { 
        ... 
        int **a; 
        func(&a, 2, 3); 
        ... 
    } 
    
  2. Сделайте это методом C++: передайте ссылку.

    void func(int **&a, int x, int y) { 
        //  ^
        // This is the only change. Neat! 
    
  3. ли это правильное (на мой взгляд) способ: вернуть значение из функции, и инициализируется массив из этого.

    int **func(int x, int y) { 
        int **a = new int*[x]; // EDIT: Fixed stupid typo bug 
        // existing code 
        return a; 
    } 
    
    int main(int argc, char **argv) { 
        ... 
        int **a = func(2, 3); 
        ... 
    } 
    
+0

Второй способ - это то, что я искал, теперь он работает безупречно. Спасибо, что сравнили 3 разных способа. – user1647798

1

Что делает ваш исходный код, это изменение локальной переменной в func, а не локальная переменная в main. Это будет делать то, что вы хотите:

void func(int **&a, int x, int y) { 
    a = new int*[x]; 

    for (int i=0; i<x; i++) 
      a[i] = new int[y]; 
} 

void main() { 
    int **a;  
    func(a, 2, 3); 
} 

В противном случае я не могу понять, почему вы бы получить ошибку сегм, если вы пытаетесь получить доступ к массиву в основном после вызова FUNC.

0

В вашем первом примере. звонок func не изменяет значение a в main. Вы можете иметь func возвращают указатель на массив он создает, а затем присвоить этот указатель на переменную в main. Изменение образца кода будет выглядеть следующим образом:

int** func(int x, int y) { 
    int **a = new int*[x]; 

    for (int i=0; i<x; i++) 
     a[i] = new int[y]; 

    return a; 

} 

void main() { 
    int **a;  
    a = func(2, 3); 
} 
Смежные вопросы