#c #arrays #function #memory #struct
#c #массивы #функция #память #структура
Вопрос:
Существует двумерный массив структур, я передаю указатель массива на функцию:
result.capabilities = (Capabilities **)malloc(sizeof(Capabilities *)*6);
for(int i=0;i<6;i ){
result.capabilities[i] = (Capabilities *)malloc(sizeof(Capabilities)*8);
}
init_capabilities(amp;result.capabilities);
Вызов функции вызывает ошибку:
Необработанное исключение в 0x003c10f9 в solution.exe : 0xC0000005: Местоположение записи с нарушением доступа 0xfdfdfdfd.
Вот моя функция:
void init_capabilities(Capabilities ***capabilities) {
for(int i=0;i<6;i ){
for(int j=0;j<8;j ){
printf("%d %dn",i,j);
capabilities[i][j]->room_capabilities = new RoomCapability[rooms_count];
}
}
}
Я думал, что размерность массива capabilities
— 6×8. Оказалось, что 1×6.
Час головной боли из-за этого. Показать вам, как изменить тип аргумента или как ссылаться на элементы моего массива, чтобы все встало на свои места?
Комментарии:
1. Это C или C ? Потому что я думаю, что смогу вам помочь, если вы пишете на C , используя
new
вместоmalloc()
того, что предоставляет C (что дает вам гораздо более чистый, простой синтаксис и безопаснее, чемmalloc()
IIRC).2. Это действительно плохой код смешивания C / C . И когда я говорю «плохо», я имею в виду именно это. Не используйте
malloc
в C . Используйте ссылки на C , когда это возможно и осуществимо.3. Не будь программистом с тремя звездами . Это приносит только боль.
Ответ №1:
Вы передаете указатель на указатель на возможности по указателю. Вот почему у вас три звездочки вместо двух.
Попробуйте это:
void init_capabilities(Capabilities ***capabilities) {
for(int i=0;i<6;i ){
for(int j=0;j<8;j ){
printf("%d %dn",i,j);
// Note: extra dereference:
(*capabilities)[i][j].room_capabilities = new RoomCapability[rooms_count];
}
}
}
Или это:
result.capabilities = (Capabilities **)malloc(sizeof(Capabilities *)*6);
for(int i=0;i<6;i ){
result.capabilities[i] = (Capabilities *)malloc(sizeof(Capabilities)*8);
}
init_capabilities(result.capabilities); // Note NO address-of operator
// Note: two stars, not three
void init_capabilities(Capabilities **capabilities) {
for(int i=0;i<6;i ){
for(int j=0;j<8;j ){
printf("%d %dn",i,j);
capabilities[i][j].room_capabilities = new RoomCapability[rooms_count];
}
}
}
Или, поскольку вы кодируете на C , а не на C:
// Assuming that result.capabilities and Capabilties::room_capabilities are declared
// vectors of the appropriate types ...
result.capabilities = std::vector<std::vector<Capabilities> >(std::vector<Capabilities>(8),6);
init_capabilities(result.capabilities);
void init_capabilities(std::vector<std::vector<Capabilities>amp; capabilities) {
for(int i=0;i<capabilities.size();i ){
for(int j=0;j<capabilties[i].size();j ){
printf("%d %dn",i,j);
capabilities[i][j].room_capabilities.resize(rooms_count);
}
}
}
Комментарии:
1. В
init_capabilities
, разве это не должно быть.
вместо->
?
Ответ №2:
Объявить
void init_capabilities(Capabilities ***capabilities)
как
void init_capabilities(Capabilities **capabilities)
и вызовите
init_capabilities(result.capabilities);
Вам просто нужно передать указатель на вашу структуру массива, а не указатель на указатель вашей структуры массива.
Редактировать: И, как указывали другие, если вы собираетесь использовать C , вы действительно должны использовать new
as в:
result.capabilities = new (Capabilities *)[6];
for(int i=0;i<6;i ) {
result.capabilities[i] = new Capabilities[8];
}
init_capabilities(result.capabilities);
…
void init_capabilities(Capabilities **capabilities) {
for(int i=0;i<6;i ) {
for(int j=0;j<8;j ) {
capabilities[i][j].room_capabilities = new RoomCapability[rooms_count];
}
}
}
И не забудьте использовать delete[]
. А еще лучше, сделайте так, как предлагает Роб, и используйте предопределенные контейнеры C для обработки такого рода вещей. Но если вы действительно хотите использовать небезопасные указатели, то то, что я привел выше, должно сделать это за вас.
Ответ №3:
Здесь у вас целый ряд проблем:
- Вы выделяете пространство для каждой отдельной возможности, затем создаете новую, превращая выделенное пространство в мусор
- Вы рассматриваете возможности как 2d-массив, когда на самом деле это массив указателей на массивы
- Вы передаете адрес этого всего массива, но ничего не делаете, чтобы отразить его в функции
Пока вы не поймете, что пытаетесь сделать, КАК это сделать, придется подождать.