Вопрос для начинающих: указатель на указатель / Не удается получить доступ к значениям извне функции - PullRequest
0 голосов
/ 14 мая 2011

Я передаю указатель на указатель (** resultSet) на мою функцию MySQL.

Вот выдержка из того, как я копирую данные MySQL из функции:

int
getItems(char * cmd, char **resultSet)
{

...
MYSQL initialisations and set-up
...



    resultSet = malloc(sizeof(char)*(int)mysql_num_rows);

    while((row = mysql_fetch_row(result))) 
    {

            for (i=0 ; i < mysql_num_fields(result); i++)               
            {   
            printf("%i: \t", i);        
            resultSet[counter] = malloc(sizeof(char)*strlen(row[i])+1);
            strcpy(resultSet[counter], row[i]);
            printf("%s\n", resultSet[counter]);
            }
            printf("---------------------\n");
            counter++;      
    }
...
MYSQL cleaning up
...
return 0;
}

Вызов его в основном с помощью

getItems(cmd, resultSet);

Изнутри моей функции getItems это

printf("%s\n", resultSet[0]);

, кажется, работает.

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

Ответы [ 5 ]

2 голосов
/ 14 мая 2011

Вы, вероятно, хотите:

resultSet = malloc(sizeof(void *)*(int)mysql_num_rows);

Вместо:

resultSet = malloc(sizeof(void)*(int)mysql_num_rows);

так как вам нужны указатели, а не байты.

1 голос
/ 14 мая 2011

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

resultSet = malloc(sizeof(char*)*(int)mysql_num_rows);

Для отражения этого (примечание char *).

Также:

resultSet[counter] = malloc(sizeof(char)*strlen(row[i])+1);

Эта строка технически правильна, новы должны изменить его на:

resultSet[counter] = malloc(sizeof(char) * (strlen(row[i])+1) );

Чтобы отразить то, что вы действительно хотите сделать (причина этого в том, что C выполняет арифметику, и первый подход даст неверные результаты, если вы попытаетесь это сделатьна любом другом типе данных, кроме char / unsigned char).

Наконец, я ожидаю, что вы захотите как-то вернуть значение 2d-массива.Есть два способа сделать это:

  1. Заставить функцию возвращать символ ** (возвращать NULL при ошибке).Здесь вам не нужен resultSet в качестве входного параметра.
  2. int getItems (char * cmd, char *** resultSet)

Обратите внимание, что все с resultSet в функции будет иметьизменить на * resultSet.Затем функцию можно вызвать с помощью:

char **result;
int status = getItems(cmd, &result);
1 голос
/ 14 мая 2011

Две проблемы здесь:

  • Как указано, распределение результатов неверно.
  • Во-вторых, strlen (строка [i] +1) вычислит длину строки ячейки памяти, на которую ссылается строка [i] +1. Эта длина будет на 1 меньше длины строки строки [i]. Поскольку вы в основном дублируете строку с нулевым символом в конце, используйте эту функцию: resultSet[counter] = strdup((char *)row[i]);

Нет необходимости в malloc и strcpy.

1 голос
/ 14 мая 2011

Если вы хотите использовать resultSet в качестве возвращаемого параметра, вам нужно сделать подпись функции

int getItems(char * cmd, char ***resultSet)

и используйте его в функции как

*resultSet = malloc(sizeof(char)*(int)mysql_num_rows)

Вызов функции может выглядеть как

char** results;
nitems = getItems(somecmd, &results); 

Лучше и проще, вероятно, оставить все как есть и произвести распределение до вызова функции.

0 голосов
/ 14 мая 2011

Возможно, вам просто нужно установить возвращаемое значение (или параметр) в & resultSet. Но мы могли бы точно знать, показали ли вы параметры функции и вызов функции.

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