Как передать двумерный массив структур в функцию?

#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:

Здесь у вас целый ряд проблем:

  1. Вы выделяете пространство для каждой отдельной возможности, затем создаете новую, превращая выделенное пространство в мусор
  2. Вы рассматриваете возможности как 2d-массив, когда на самом деле это массив указателей на массивы
  3. Вы передаете адрес этого всего массива, но ничего не делаете, чтобы отразить его в функции

Пока вы не поймете, что пытаетесь сделать, КАК это сделать, придется подождать.