Задача:
Пишу код на Си. Есть массив строк, к примеру всего 8 строк по 64 символа, т.е. char str[8][64].
Этот массив заполняется строками, переданными через аргументы командной строки.
Я хочу вывести строки массива str на экран и никаких проблем у меня не возникает, когда я делаю это в функции, где и создавал этот массив.
Я хочу сделать функцию strArrOut(char **arr, int size), которая бы выводила на экран массив строк, когда в неё передают указатель на этот массив и размер этого массива.
Но когда я пытаюсь разыменовать этот указатель в функции, то получаю ошибку "Нарушение прав доступа при чтении по адресу 0xFEFEFEFE", хотя я точно знаю, что по адресу, который содержится в переданном указателе, точно что-то есть. Долго и упорно гуглил, но наверное я слепой, либо чего-то не понимаю (Хотя по-моему в C++ я делал похожую вещь и обращался к элементам переданного массива через [ ] и всё работало, но тут не получается).
Вот код:
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>
void strArrOut(char** arr, int size);
int main(int argc, char* argv[]) {
setlocale(LC_ALL, "Russian");
char str[8][64];
int strc = argc - 1;
//Заполняю массив тем, что передано через командную строку
for (int i = 1; i < strc + 1; i++) {
strcpy_s(str[i - 1], sizeof(str[i - 1]), argv[i]);
}
//Пытаюсь вывести первую строку массива - без ошибок
printf("p: %p", str);
printf("\n*p: %s", *str);
//Пытаюсь вывести первую строку массива, но передавая указатель в функцию
printf("\nВходные строки: ");
strArrOut(str, strc);
return 0;
}
void strArrOut(char** arr, int size) {
printf("\np: %p", arr); // Выдает тот же адрес, что и str
printf("\np: %s", arr); // Ошибка: нарушение прав доступа при чтении по адресу 0xFEFEFEFE
//printf("\n*p: %s", arr[0]); - выдаёт ту же ошибку
}
В чем проблема? Разве я не всегда могу получить значение по адресу, если точно знаю, что за ним есть какое-то значение?
UPD: Рабочее решение: заменить строку void strArrOut(char** arr, int size); на void strArrOut(char arr[][64], int size);, так всё работает, но всё же интересно было бы услышать предложения почему нельзя разыменовать указатель char **arr. При схожей конструкции, но с передачей указателя на одномерный массив (т.е. char *arr), разыменовать указатель получается, а тут нет.
char str[8][64]иchar**str- два глубоко различных типа... – Harry May 25 '21 at 12:04void strArrOut(char** arr, int size);=>void strArrOut(char arr[][64], int size);– AlexGlebe May 25 '21 at 12:23char str[8][64]иchar **strразличные типы, но ведьstrпредставляет собой указатель на указатель на тип char, насколько я помню. – leonidsah May 25 '21 at 14:37