используя указатель на массив символов - PullRequest
0 голосов
/ 26 апреля 2011

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

struct record ** getRegEx( int *counter, char** keys )
{
    *counter = 0;
   //get some records, its number is *counter, max lenght of each string is 64

   //COUNTER IS NOT 0! ITS VALUE DEPENDS ON OTHER OPERATIONS I HAVENT WRTTEN HERE
   //...        
    keys =(char ** ) malloc((*counter)*(sizeof(char *)));
    for (j = 0; j < *counter; j++)
    {
      keys[j] = (char* )malloc(64*sizeof(char));            
    }

    strcpy(keys[j],key.dptr);

    printf("size %d : \n", sizeof(**keys));//1
    printf("size %d : \n", sizeof(*keys));//4
    printf("size %d : \n", sizeof(keys[0]));//4
    printf("size %d : \n", sizeof(keys));//4    
   //...
}


/*Out of the function, inside the function OK*/
char**   keys;
int count;  
results = getRegEx(&count, &keys); //&keys or keys - makes no difference
for(int k=0 ; k< *count;k++) //test
{
    printf("keys in db %s: s\n", keys[k]); //nothing!?
}

Я сделал это, заменив заголовок функции чем-то вроде struct record ** getRegEx( int *counter, char*** keys ) (и используя * ключи и * ключи [i] вместо ключа и ключей [i] внутри функции). Спасибо за все!

Ответы [ 4 ]

3 голосов
/ 26 апреля 2011

Вы передаете ноль в malloc, поэтому вам нечего возвращать в keys.

Ваш цикл for никогда не запускается.

И то и другое, потому что (*counter) равно нулю.

2 голосов
/ 26 апреля 2011
  1. Здесь серьезная проблема:

    results = getRegEx(&count, &keys); //&keys or keys - makes no difference
    

    Ваш комментарий неправильный - он действительно имеет значение. keys имеет тип char ** (который ожидает getRegEx), &keys имеет тип char ***.

  2. Ваша функция имеет тип возврата, но ничего не возвращает.

  3. Вы выделяете динамическую память для своей переменной keys в функции, но функция (как она написана) не может передать эту память из функции. Ваша функция должна принимать char ***, и вы должны передавать ее как &keys (которая, как уже говорилось, имеет тип char ***.)

  4. Ваш размер всегда будет равен нулю, поскольку вы устанавливаете *count = 0 в начале своей функции (когда вы вообще не должны устанавливать его в своей функции, и должны пропускать count через значение вместо указателя). Точные эффекты malloc(0) определяются реализацией.

  5. Вы приводите возвращаемое значение malloc. Это не так, но в C это не нужно (и если вы действительно используете C ++, вам следует так сказать) и может усложнить задачу в будущем.

  6. Вы никогда не проверяете возвращаемые значения malloc на отказ.

  7. Вы используете указатель counter вне функции, в которой он объявлен. Вне вызова функции вы должны использовать переменную count, которую вы передали в качестве параметра. Параметры функций не продолжают существовать вне функций, в которых они используются.

1 голос
/ 26 апреля 2011

Основные проблемы:

  1. Ваши типы не совпадают.В вызове getRegEx(&count, &keys) тип выражения &keys равен char ***, а не char **.Обратите внимание, что если вы хотите изменить значение keys, вам придется передать на него указатель.Это приводит к следующей проблеме ...

  2. Поскольку вы изменяете значение параметра keys, а не то, на что оно указывает, любые изменения, внесенные в функцию, не являютсяотражается в звонилке.

Вот модифицированная версия вашего кода, иллюстрирующая то, что я думаю вы пытаетесь сделать:

struct record **getRegEx(int *counter, char ***keys)
{
   ...
   // type of keys = char ***
   // type of *keys = char **
   // type of **keys = char *

   *keys = malloc(*counter * sizeof **keys); // note no cast, operand of sizeof
   if (*keys)
   {
     int j;
     for (j = 0; j < *counter; j++)
     {
       // type of (*keys)[j] == char *
       // type of *(*keys)[j] = char

       (*keys)[j] = malloc(64 * sizeof *(*keys)[j]); 
     }
   }
   ...
}

Обратите внимание, что я нене произнесите результат malloc.Начиная с версии C, выпущенной в 1989 году, вам это не нужно, так что это избавляет от визуальных помех.Это также защищает вас от потенциальной ошибки;если вы забудете включить stdlib.h или иным образом не создавать прототип для malloc в области видимости, компилятор примет функцию, возвращающую int.Без приведения вы получите диагностику в порядке «несовместимых типов для назначения».Добавление приведения подавит диагностику, и в результате вы можете иметь незначительные (или не очень тонкие) ошибки времени выполнения.

Также обратите внимание, что я использую sizeof на объектах , не типы.Опять же, это помогает уменьшить визуальный беспорядок, а также защищает вас в случае, если вы решите изменить базовый тип keys;Вам также не нужно обновлять каждый malloc звонок.

Почему (*keys)[j] вместо *keys[j]?Выражение keys - это не местоположение начала нашего массива, а указывает на это местоположение.Нам нужно разыменовать keys, чтобы получить адрес массива, который мы затем расшифруем.

0 голосов
/ 26 апреля 2011

У вас есть функция getRegEx, объявленная для возврата struct record **.

Вы знаете, чего не хватает в этой функции?
все, что выглядит как return оператор!

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