2016-02-09 2 views
1

Я пытаюсь записать данные в двумерный массив переменной длины, и моя программа сохраняет seg-faulting, когда я вызываю myfunc, но он отлично работает, когда я пытаюсь выполнить ту же манипуляцию за пределами функция. Я могу сказать, что проблемы заключаются в том, что адрес, указанный в массиве [0], не равен адресу, указанному в данных [0]. Может ли кто-нибудь посоветовать мне о первопричине этой проблемы и надлежащем способе перезаписи myfun.Манипулировать двумерный массив переменной длины с помощью функции

void myfun(unsigned char **array){ 
    printf("array = %p, array[0] = %p\n", array, array[0]); 
    //This line below causes a segfault 
    strcpy(array[0], "Position0"); 
} 

int main(void) { 
    int row = rand() % 5 + 1; // random number between 1-5 
    int col = rand() % 10 + 20; // random number between 20-29 
    unsigned char data[row][col]; 

    printf("data = %p, data[0] = %p\n", data, data[0]); 

    //This function call causes a segfault 
    myfun(data); 
    printf("%s\n", data[0]); 

    //This works 
    strcpy(data[1], "Position1"); 
    printf("%s\n", data[1]); 

    return 0; 
} 
+0

В вашем тексте вы говорите, что получаете операцию segfault при выполнении операции внутри 'myfun', но не тогда, когда вы выполняете ее вне функции; комментарий в вашем коде говорит наоборот. – Beta

+0

Я только что обновил комментарии в коде, чтобы быть более понятным. Строкой, вызывающей segfault, является «strcpy (массив [0],« Position0 »); – jprince14

+1

Ваш компилятор должен был предупредить вас, что 'char [x] [y]' несовместим с 'char **', и вы должны были прослушать это предупреждение, потому что это правда. Если он вас не предупредил, узнайте, как включить предупреждения. –

ответ

3

Поскольку вы явно используете C99 или более позднюю версию и компилятор с VLA (переменная массива длиной) поддержкой, вы можете написать функцию правильно довольно легко:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

static void myfun(int rows, int cols, char array[rows][cols]) 
{ 
    printf("array = %p, array[0] = %p\n", array, array[0]); 
    strcpy(array[0], "Position0"); 
    printf("a[0] = [%s]\n", array[0]); 
} 

int main(void) 
{ 
    int row = rand() % 5 + 1; // random number between 1-5 
    int col = rand() % 10 + 20; // random number between 20-29 
    unsigned char data[row][col]; 

    printf("data = %p, data[0] = %p\n", data, data[0]); 

    myfun(row, col, data); 
    printf("%s\n", data[0]); 

    strcpy(data[1], "Position1"); 
    printf("%s\n", data[1]); 

    return 0; 
} 
1

Проблема заключается в определении функции. Если вы хотите передать матрицу так, как вы это делали, вам нужно распределить ее динамически, но это уже другая история. Я объясню ошибку.

Язык C фактически реализует статические матрицы как один массив строки размера * col. Это для эффективности.

Когда вы передаете статическую матрицу этой функции, у вас возникает проблема: она ожидает двойной указатель, но то, что вы передаете, на самом деле является единственным указателем, требующим количества столбцов. Вы должны написать так:

void myfun(unsigned char array[][col]){ ... 

Вот как вы должны определить его, где цв это число столбцов.

Проблема в том, что вы не знаете количество столбцов, это переменная, поэтому я предлагаю вам использовать malloc или calloc для распределения динамической матрицы.

Редактирование: посмотреть эту ссылку, размещенную как комментарий от n.m. подробно о статической матрице, C реализует: Is 2d array a double pointer?

+2

С C99 или C11 и VLA (массив переменной длины), вы можете обращаться с ним чисто, не требуя динамического распределения памяти. –

+1

Мне нравится метод malloc: я получил его для работы со следующим кодом: 'data2 = (unsigned char **) malloc (строка * col); myfun_malloc (data2); 'void myfun_malloc (char ** array) { printf ("В myfun_malloc: array =% p, array [2] =% p \ n", array, (array + (2 * sizeof (char *)))); strcpy (массив + (2 * sizeof (char *)), «Position2»); printf ("a [2] = [% s] \ n", (массив + (2 * sizeof (char *)))); } ' – jprince14

+0

Я бы предпочел использовать динамическое, а не полудинамическое решение в этом конкретном случае. Тем не менее, я ценю отзывы о VLA. Важно знать разницу в эффективности использования полудинамических распределенных массивов. –

Смежные вопросы