Преобразование типов void* в char ** (язык Си)
Пишем с сокомандником проект, сокомандник записывает различные аргументы в переменную void* ptr как двумерный массив, а я потом получаю данный void* ptr и должен обработать его как char**.
Понимаю, как работает кастинг на базовом уровне (преобразование типов)
void* ptr;
char** ptrchar;
ptrchar = (char**)ptr;
Но мне кажется, что такое преобразование типов не будет работать, т.к. передается указатель на одномерный массив void, а мне нужно работать с двумерным массивом? Есть ли ошибка в нашей логике?
И прошу описать, как надо сделать кастинг из таких разных типов, если это действительно работает.
Ответы (1 шт):
Ошибка в логике есть. Тип char** это не указатель на двухмерный массив. Это указатель на указатель на char. Его же можно трактовать как указатель на одномерный массив указателей на одномерные массивы char (либо одиночные char). А если нужен указатель именно на двухмерный массив, то он определяется так:
char (*ptrchar)[NUM_COLUMNS];
И динамически создаётся так (С++):
ptrchar = new char[NUM_ROWS][NUM_COLUMNS];
Или так (в C):
ptrchar = (char(*)[NUM_COLUMNS])malloc(sizeof(char)*NUM_ROWS*NUM_COLUMNS);
Как видите, количество столбцов должно быть явно указано в типе и оно не может быть переменной. Это связано с тем, что двухмерный массив - это массив одномерных массивов, и чтобы вычислить позицию заданного элемента по индексам i и j компилятору необходимо знать ширину строки (число столбцов).
Что касается приведения указателя к void* и хранения его в этом типе, то ключевой вопрос: зачем? Тут тоже отчётливо пахнет ошибочной логикой, хотя вы не привели конкретный код. С подобными преобразованиями типов указателей надо обращаться крайне осторожно, т.к. они легко могут приводить к неопределённому поведению.