Указатель на сегменты 2D-массива - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть следующий минимальный пример, где моя основная функция вызывает две разные функции function1() и function2().Они оба хотят работать с таблицей, которую необходимо сгенерировать при первом запуске function1().В моей реальной программе таблица намного больше, поэтому я не хочу, чтобы она была жестко запрограммирована в памяти программы как глобальная переменная, а вычислялась в первом раунде кода.Я объявил таблицу статической, так что она сохраняет назначенные значения при выходе из функций.Я не уверен, должен ли tblPtr быть static тоже.Почему я получаю SEGFAULT здесь?

#include <stdio.h>

static void genTbl(unsigned int encodeTbl[][2])
{
    int nn,mm;
    for (nn=0; nn < 3;nn++){
        for (mm=0; mm < 2; mm++){
            encodeTbl[nn][mm] = nn+mm; //some example
        }
    }
}
unsigned int **tblPtr;          //pointer to table
static unsigned int function1()
{
    static int t1=0;
    static unsigned int tbl[3][2];
    if(t1==0){ //only gen table in first round
        t1++;
        genTbl(tbl);
        tblPtr = &tbl; //assign pointer 
        t1++;
    }
    return (tbl[2][2]);
}
static unsigned int function2()
{
   //also wants to work with tbl
   return (tblPtr[2][2]);   //SEGFAULT
}

int main()
{
    int cnt=0;
    while(cnt<5){
        int f1 = function1();
        printf("function1 return: %d\n", f1);
        int f2 = function2();
        printf("function1 return: %d\n", f2);
        cnt++;
    }
}

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Объявите tblPtr как пользовательский тип с

typedef unsigned int myType[3][2];
myType **tblPtr;          //pointer to table

С помощью этого метода вы объявите его явно как указатель на двумерный массив беззнаковых целых.А затем поместите static unsigned int tbl[3][2] вне функции 1

0 голосов
/ 28 ноября 2018

В вашем function1() вы уже вызвали неопределенное поведение .

Вы определили массив как static unsigned int tbl[3][2];, поэтому допустимый доступ будет tbl[i][j];, где 0<i<3 и 0<j<2.Таким образом, в коде

return (tbl[2][2]);

используется память вне пределов, она смещена на единицу .У вас такая же проблема и в function2().

Тем не менее, оператор

 tblPtr = &tbl; 

недопустим и является нарушением ограничения.Любой соответствующий компилятор с включенными надлежащими предупреждениями предупредит вас об утверждении.Вам нужно изменить тип tblPtr, чтобы он был указателем на массив 2 int s, что-то вроде

 unsigned int (*tblPtr)[2];  

, и тогда присвоение будет действительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...