0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
1

Ошибка при обращении к двумерному массиву char, размещенному в стеке, из другой функции

25.12.2015, 16:27. Показов 1253. Ответов 15
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
int main() {
    char s[2][6] = { "test1\0", "test2\0" };
    foo(s);
}
 
void foo(char** array) {
    putchar(arr[0][0]); //ошибка - чтение 0x00000000
}
C++
1
2
3
4
5
6
7
8
9
10
int main() {
    char** s = (char**)malloc(sizeof(**s) * 2);
    s[0] = (char*)malloc(sizeof(*s) * 6);
    data[0] = "test1\0";
    foo(s);
}
 
void foo(char** array) {
    putchar(arr[0][0]); //ошибки нет
}
C++
1
2
3
4
5
6
7
8
int main() {
    char *s[2][6] = { "test1\0", "test2\0" };
    foo(s);
}
 
void foo(char** array) {
    putchar(arr[0][0]); //ошибки нет
}
C++
1
2
3
4
int main() {
    char s[2][6] = { "test1\0", "test2\0" };
    putchar(arr[0][0]); //ошибки нет
}
Объясните, пожалуйста, почему так происходит. И почему нет ошибки, если вызвать "putchar(arr[0][0]);" из функции main?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.12.2015, 16:27
Ответы с готовыми решениями:

Индекс за пределами диапазона при обращении к двумерному массиву
такая проблема, в текстбоксе есть такие числа например: 33 23 31. 3 и 3, 2 и 3, 3 и 1 это...

Не получается присвоить значение двумерному массиву char
объявляю двумерный массив (массив массивов в char для хранения имен файлов) в cpp файле char...

Ошибка при обращении к массиву
public class PrintText{ public String arrayString = {"ivanov;Ivan...

Выберите строку, в которой есть ошибка при обращении к массиву
Дано описание массива в разделе описания переменных: Var a: array of integer; Выберите...

15
Хитрая блондиночка $)
1464 / 979 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
25.12.2015, 16:37 2
А полностью код?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31268 / 20438 / 7970
Регистрация: 22.10.2011
Сообщений: 35,491
Записей в блоге: 6
25.12.2015, 16:42 3
Цитата Сообщение от takexowuf Посмотреть сообщение
//ошибка - чтение 0x00000000
gcc, например, вообще отказывается компилировать первый код.
0
0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
25.12.2015, 16:50  [ТС] 4
А полностью код?
Больше ничего интересного нет, только прототип функции и подключение стандартной библиотеки. Во всех остальных примерах меняются только указанные в заглавном посте строки.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
void foo(char**);
 
int main() {
    char s[2][6] = { "test1\0", "test2\0" };
    foo(s);
    return 0;
}
 
void foo(char** arr) {
    putchar(arr[0][0]);
}
gcc, например, вообще отказывается компилировать первый код.
Можно увидеть, на что он ругается?
Указанный код успешно собирается MS Visual Studio 2008.
0
Нарушитель
Эксперт C
26240 / 16270 / 3525
Регистрация: 24.12.2010
Сообщений: 35,916
25.12.2015, 17:15 5
Лучший ответ Сообщение было отмечено takexowuf как решение

Решение

takexowuf, Дело в том, что s[2][6] и **s - вещи немного разные. Хоть и говорится, что в Си массив и указатель - одно и тоже, однако в двумерном случае это не совсем так.
В любом случае, функцию foo (или ее прототип) надо поместить перед вызовом. Тогда и у вас вариант 1 выдаст ошибку.
Но рассмотрим 1-й вариант в вашем исполнении. char s[2][6] - это кусок памяти величиной 12 байт.
foo(s) - вы передаете функции foo указатель на этот кусок (его адрес)
Что думает функция foo(char **a) ?
Она думает, что ей передали указатель на указатель.
a[0] для нее это указатель на char. a[0][0] - байт, расположенный по адресу, который помещается в 1-х четырех байтах массива s. А там вместо этого невразумительный (для foo) текст.

Добавлено через 2 минуты
А вот так (вариант, вами не испробованный) все будет Ок!
C
1
2
3
4
5
6
7
int main() {
    char s[2][6] = { "test1\0", "test2\0" };
    foo(s);
}
void foo(char* array[6]) {
    putchar(arr[0][0]); 
}
Добавлено через 4 минуты
Еще хочу добавить, что в варианте 2 вы не совсем правильно вычисляете размер памяти для malloc.
А в варианте 3 - вообще не понятно что, и отсутствие ошибки в нем - ваше невероятное везение.
2
0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
25.12.2015, 17:18  [ТС] 6
Хоть и говорится, что в Си массив и указатель - одно и тоже, однако в двумерном случае это не совсем так
Получается, это выделенная память в нужном количестве (по количеству измерений) под "конечный" (в данном случае char, 1 байт. а не char*-указатель четырехбайтовый) тип данных? Нашел только такое объяснение.
Благодарю за помощь
0
Нарушитель
Эксперт C
26240 / 16270 / 3525
Регистрация: 24.12.2010
Сообщений: 35,916
25.12.2015, 17:23 7
takexowuf, по вашему посту я так и не понял, разобрались ли в том, что такое УКАЗАТЕЛЬ вообще, и что происходит в вашем примере в частности. Надеюсь, разберетесь. Главное понять, что указатель - это адрес. А указатель на указатель - адрес адреса.
Если еще остались непонятности - спрашивайте дальше.
1
0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
25.12.2015, 17:55  [ТС] 8
Если еще остались непонятности - спрашивайте дальше.
Более-менее разобрался, насколько я вижу. Больше интересно про:

Хоть и говорится, что в Си массив и указатель - одно и тоже, однако в двумерном случае это не совсем так
Правильно понимаю, что в случае многомерного массива указателем является только "его имя" (указывающее на нулевой, самый первый элемент массива), а все остальное - матрица всех значений, расположенная в памяти, обращение к которой идет по индексам? Ох, получается очень странная формулировка, знаю
0
Нарушитель
Эксперт C
26240 / 16270 / 3525
Регистрация: 24.12.2010
Сообщений: 35,916
25.12.2015, 20:43 9
Лучший ответ Сообщение было отмечено takexowuf как решение

Решение

Цитата Сообщение от takexowuf Посмотреть сообщение
Правильно понимаю, что в случае многомерного массива указателем является только "его имя" (указывающее на нулевой, самый первый элемент массива), а все остальное - матрица всех значений, расположенная в памяти, обращение к которой идет по индексам? Ох, получается очень странная формулировка, знаю
Имхо, понимаете правильно. И ничего странного не вижу.
Уточню, хотя думаю, что это понятно. "Его имя" (адрес)(А) является указателем на элемент с индексом [0][0]...[0]
Адреса всех остальных элементов вычисляются по формуле A + N1*N2*i1 + N2*i2 + i3 (для 3-х мерного массива A[N1][N2][N3] это элемент a[i1][i2][i3]). Это позволяет массивы любой мерности представлять в виде линейных (одномерных) и брать индексацию на себя. Что иногда бывает чрезвычайно полезно. Особенно для 7-ми мерных массивов
Но когда вы определяете массив через серию вложенных malloc-ов (new для плюсов), тут получается совсем другая организация памяти. Она слегка избыточна, зато более гибкая.
И когда функция имеет вид foo(**x) она считает, что массив организован именно так. То есть как указатель на массив указателей.
Удачи!

Добавлено через 5 минут
ЗЫ. Я ничего не говорил о том, что все формулы подразумевают умножение на sizeof(тип). Си это делает за вас. Но при выделении памяти (то есть по-байтовой работе) это надо иметь в виду. И надо понимать, на что именно, на данные какого типа, выделяется память.
1
0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
25.12.2015, 20:45  [ТС] 10
ЗЫ. Я ничего не говорил о том, что все формулы подразумевают умножение на sizeof(тип). Си это делает за вас. Но при выделении памяти (то есть по-байтовой работе) это надо иметь в виду. И надо понимать, на что именно, на данные какого типа, выделяется память.
О. Вот в чем была причина прошлых непоняток с памятью, точнее, ее выделением. Спасибо еще раз
0
Хитрая блондиночка $)
1464 / 979 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
25.12.2015, 20:47 11
Цитата Сообщение от Байт Посмотреть сообщение
putchar(arr[0][0]);
Я чего-то не вижу? А где переменная эта описана? Как вообще это может скомпилироваться то?
0
Нарушитель
Эксперт C
26240 / 16270 / 3525
Регистрация: 24.12.2010
Сообщений: 35,916
25.12.2015, 20:59 12
Цитата Сообщение от Hikari Посмотреть сообщение
Я чего-то не вижу? А где переменная эта описана? Как вообще это может скомпилироваться то?
Простите, Бога ради! Конечно, любой компилятор увидев этот код справедливо возмутится. И любой копипастящий школяр тоже будет справедливо недоволен. Но, если вы заметили, разговор идет вовсе не о том. И на вашем месте я бы ваше остроумное замечание окружил бы тегами OFF.
0
Хитрая блондиночка $)
1464 / 979 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
25.12.2015, 22:08 13
Цитата Сообщение от Байт Посмотреть сообщение
остроумное замечание
Не вижу ничего остроумного. Но раз тут профессионалы с высокой репутацией считают меня слишком комичной, значит более в этой теме мне делать нечего.
И кстати, раз уж меня обвинили в остроумии: Этот вопрос был риторическим и адресовался прежде всего автору темы.
На сим дискуссию закончу.
1
0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
25.12.2015, 22:47  [ТС] 14
Цитата Сообщение от Hikari Посмотреть сообщение
Этот вопрос был риторическим и адресовался прежде всего автору темы.
И правду, не компилируется! Что посоветуете сделать? Может, это можно как-то исправить? Или это слишком сложно будет?
0
Байт
25.12.2015, 23:48
  #15

Не по теме:

Цитата Сообщение от takexowuf Посмотреть сообщение
И правду, не компилируется! Что посоветуете сделать? Может, это можно как-то исправить? Или это слишком сложно будет?
Надеюсь, это шутка?:D
А у уважаемой Hikari я искренне прошу прощения.

0
0 / 0 / 0
Регистрация: 25.12.2015
Сообщений: 7
26.12.2015, 10:25  [ТС] 16

Не по теме:

Надеюсь, это шутка?

Не по теме:

Разумеется :D

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.12.2015, 10:25

В какой строке кода есть ошибка при обращении массиву?
Дано описание массива в разделе описания переменных: Var a: array of integer; Выберите...

Ошибка при присваивании массиву char значения
В общем, требуется присвоить массиву чаров одно из нескольких значений (в зависимости от значения...

Ошибка "Bad allocation" при обращении к массиву
Такая проблема: выбивает bad allocation в 59 строке мейна. Запустите программу, введите 2 числа и...

По двумерному массиву массиву А получить одномерный массив В, присвоив его k-му элементу значение TRUE
По двумерному массиву массиву А получить одномерный массив В, присвоив его k-му элементу значение...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.