Ошибка сегментирования 3D-указателя

Я хочу соединить 2D-массивы в 3D-массив, сначала я определил 3D-массив следующим образом

int ***grid;
grid=new int **[number];

Затем я хочу назначить 2D-массивы для 3D-конструкции

for(i=0;i<number;i++)
grid[i]=rk4tillimpact2dens(...);

с

int** rk4tillimpact2dens(...
...
static int** grid;
grid=new int*[600];
for(i=0;i<600;i++)
grid[i]=new int[600];
memset(grid,0x0,sizeof(grid));
...
return(grid);
}

пока проблем нет, все работает нормально, но когда я хочу получить доступ к 3D массиву, я получаю ошибку сегмента. Как например

printf("%d",grid[1][1][1]);

В чем моя ошибка?

Лучший,
Ханнес

-1

Решение

Ой, извините, это была опечатка в моем вопросе, я сделал

printf("%d",grid[1][1][1]);

это не работает :(. Но даже

printf("%d",&grid[1][1][1]);

или же

printf("%d",*grid[1][1][1]);

не будет работать. Странно то, что нет ошибок, если я не пытаюсь получить доступ к массиву

0

Другие решения

Во-первых, вы отбрасываете первую строку каждой матрицы с этим memset (фактический ряд просочился). Хотя технически grid[1][1][1] все еще должен быть читаемым, он может быть поврежден в другом месте.

Можете ли вы привести минимальный проверяемый пример? Это может решить вашу проблему.

0

Очистить память, выделенную для gridВы не можете сделать всю матрицу NxN одним набором памяти, это не смежная память. Поскольку каждая строка выделяется как отдельный блок памяти, вам необходимо очищать их по отдельности.

for(i=0;i<600;i++) {
grid[i]=new int[600];
memset(grid[i], 0, sizeof(int) * 600);
}

600 значение должно быть именованной константой, а не жестко закодированным числом.

А также grid не должен быть статической переменной.

0

Распечатка адреса

printf("%p",&grid[1][1][1]);

Вы печатаете адрес здесь. Вот почему вы можете не получить то, что хотите увидеть.

printf("%d",grid[1][1][1]);

Это напечатает элемент массива.

И читать вход из stdin вы будете использовать scanf() который требует, чтобы вы передали адрес переменной.

scanf("%d",&grid[1][1][1]);

Обнуление выделенной памяти

Также вы не можете получить размер массива, используя sizeof, ТАК для инициализации с 0 ты используешь memset на куски, которые выделяются сразу с new,

В вашем случае пример будет Как 1201ProgramAlarm указал

for(int i = 0; i < 600; i++){
...
memset(grid[i],0,sizeof(int)*600);
}

Есть еще один способ инициализации выделенной памяти в C ++.

grid[i]=new int[600]();

Например:

int** rk4tillimpact2dens(...
...
static int** grid;
grid=new int*[600];
for(i=0;i<600;i++)
grid[i]=new int[600]();

...
return(grid);
}
0

Вы ожидаете memset(grid,0x0,sizeof(grid)); не обнулить значения указателя, которые вы только что присвоили grid[0] Через grid[599]? Если это так, вы должны проверить эту теорию, проверив значения указателя grid[0] Через grid[599] до и после этого звонка memset, чтобы узнать, что memset делает для правда (об этом позже) массивы.

Ваша программа разыменовывает нулевой указатель, который получается непосредственно из этой строки кода. Как правило, можно ожидать сбоя при попытке разыменования нулевого указателя, поскольку нулевые указатели не ссылаются ни на какие объекты. Это объясняет ваши наблюдения за аварией и ваши наблюдения за исчезновением, когда вы комментируете этот призыв к memset, Вы не можете ожидать, что хорошие вещи произойдут, если вы попытаетесь использовать значение чего-то, что не является объектом, например, grid[1][... где grid[1] это указатель, состоящий полностью из нулевых бит

Семестр 3D массив кстати, это не значит, что ты думаешь. Массивы в C и C ++ считаются не замужем распределение, где-как то, что производит ваш код, кажется, множественный выделения, связанные в иерархической форме; Вы выделили дерево в отличие от массив, а также memset не подходит для обнулить дерево. Возможно, с этого момента ваши эксперименты могли бы лучше руководствоваться книгой об алгоритмах, таких как Алгоритмы на С, части 1-4 от Роберт Седжвик.

А пока, в C, следующее даст вам указатель на 2D массив который вы можете использовать в основном как трехмерный массив:

void *make_grid(size_t x, size_t y, size_t z) {
int (*grid)[y][z] = malloc(x * sizeof *grid);
/* XXX: use `grid` as though it's a 3D array here.
* i.e. grid[0][1][2] = 42;
*/
return grid;
}

Если предположить, make_grid возвращает что-то ненулевое, вы можете использовать один вызов memset обнулить весь массив, на который указывает эта функция, потому что есть один вызов malloc совпадая, что один вызов memset… В противном случае, если вы хотите обнулить дерево, вы, вероятно, захотите позвонить memset n раз для n предметов.

В C ++ я не думаю, что вы найдете много людей, которые препятствуют использованию std::vector вместо массивов. Вы могли бы хотеть по крайней мере рассматривать эта опция, а также другие опции, которые у вас есть (например, деревья; кажется, что вы хотите использовать дерево, что хорошо, потому что деревья имеют совершенно подходящие варианты использования, для которых массивы недопустимы, а вы не дали нам достаточно контекста, чтобы сказать, что будет наиболее подходящим для вас).

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector