Помощь в объявлении и использовании динамически выделяемого массива в C

#c #c #visual-studio-2010 #visual-c

#c #c #visual-studio-2010 #visual-c

Вопрос:

Мне нужно объявить массив массивов, и для этого я использую приведенный ниже код:

 int **  maxc = new int *[proc_num];//memory allocated for elements of rows
      for (int i = 0; i < proc_num; i  )
      {
            maxc[i] = new int[n];//memory allocated for  elements of each column.
      }
  

Проблема в том, что приведенный выше код, похоже, не компилируется. Я получаю следующую ошибку компиляции:

 A value of type "int *" cannot be assigned to an entity of type "int"
  

Вот полный код:

 //#include<math.h>
#include "stdafx.h"
#include <string>
#include <iostream>
#include <vector>
using namespace std;
/*
Banker's algorithm Implementation
*/
 int main(void)
 {
      int n=0;//number of resources we will  be dealing with 
      int proc_num =0;//Total number of processes to share available resources
      int* a = NULL;  // pointer to an int with initial set to point to nothing
     // int* maxc = NULL;
      int* maxR=NULL;
      int* avail = NULL;
      int* avail_temp = NULL;
      //int** alloc = NULL;
      int* unalloc = NULL;

      std::cout<<endl;
      std::cout <<" What is number of resources to be shared? :";
      cin >> n;
      std::cout<<endl;
      while(std::cin.fail())
      {
            std::cout<< " Error Please provide valid number !" <<endl;
            std::cin.clear() ;
            std::cout<<endl;
            std::cout <<" What is number of resources to be shared? :";
            cin >> n;
            std::cout<<endl;
      }

      maxR = new int[n];  // Allocate n ints and save ptr in maxc -- holds the max resources available.
      //get the maximum number of each Resources/ Ie Total Resources Available
      for(int i =0; i < n; i  )
      {
            int maxcin=0;
            std::cout << i;
            std::cout<< ". How many of resource #";
            std::cout<< i;
            std::cout<< " do you need to share ?"; 
            cin>>maxcin;
            maxR[i] = maxcin;
      }
      //<8,7,5,9>");

      std::cout<<endl;
      std::cout << "How many processes to share available resources?";
      cin>>proc_num;
      std::cout<<endl;

      int **  maxc = new int *[proc_num];//memory allocated for elements of rows
      for (int i = 0; i < proc_num; i  )
      {
            maxc[i] = new int*[n];//memory allocated for  elements of each column.
      }
}
  

Комментарии:

1. Есть ли какая-либо конкретная причина не использовать какой-либо из более безопасных / удобных идиоматических способов, предлагаемых C для достижения той же функциональности, что и простые многомерные массивы?

2. Если вы пытаетесь написать исходный файл на нескольких языках, я предлагаю вам не использовать new , или :: , или << (кроме как оператор побитового сдвига), или namespace , ..

3. Не могли бы вы показать полный пример, пожалуйста? Приведенный здесь код не содержит ошибок и отлично компилируется в моей собственной копии VC10 (при условии, что proc_num и n объявлены правильно).

4. Я беру это из этого примера здесь codeproject.com/KB/cpp/arrayDinamic.aspx

5. Это приятно. Но мне все еще нужно увидеть ваш полный код, основную функцию, includes и все остальное.

Ответ №1:

Ошибка, которую вы получаете сейчас, полностью отличается от той, которую вы опубликовали ранее. В заключительном цикле for —

 maxc[i] = new int*[n];
  

должно быть —

 maxc[i] = new int[n];
  

Во фрагменте, который вы опубликовали ранее, это было правильно. Кроме того, вам следует освободить ресурсы, полученные при new[] использовании delete[] , иначе имеет место утечка памяти.

Комментарии:

1. @Kobojunkie — Как все предлагали, тогда опубликуйте весь код в своем вопросе. В том, что вы опубликовали, нет ничего неправильного.

Ответ №2:

Проблема, с которой вы столкнулись, находится в этом разделе опубликованного вами кода:

 int **  maxc = new int *[proc_num];
for (int i = 0; i < proc_num; i  )
{
    maxc[i] = new int*[n];
}
  

Внутри цикла for вы выделяете новый массив int указателей, но исходный тип для maxc был типа pointer-to-pointer. В данном контексте это также можно было бы истолковать как maxc указатель, указывающий на массив указателей. Это, конечно, достигается при первом присваивании, когда вы возвращаете указатель из new , который указывает на массив int* . Следовательно, инструкция внутри цикла for присваивает неправильный тип каждому элементу массива. Типом элементов массива maxc[x] являются int указатели, что означает, что они должны указывать либо на один, либо на несколько объектов типа int , а не на элементы типа int* . Но ваш new оператор в цикле пытается выделить другой массив int указателей и возвращает указатель на этот выделенный массив, что означает, что возвращаемый тип int** снова равен, а это неверно. Итак, вам следует изменить внутреннюю часть вашего цикла на чтение:

 maxc[i] = new int[n]; //allocate an array of int's, and return an int pointer
  

Я заметил, что первый сегмент кода, который вы опубликовали, на самом деле делает это, так что, возможно, вы столкнулись с простой опечаткой, которую вы пропустили?

Наконец, когда вы удалите эту память, поскольку каждая строка была создана с использованием new , вам придется вызывать delete для каждой строки, представляющей массив int ‘s. Далее вам нужно будет вызвать delete для столбца, представляющего массив int указателей, которые указывали на массив int ‘s. Таким образом, освобождение всей выделенной памяти будет выглядеть следующим образом:

 for (int i=0; i < proc_num; i  )
{
    //call delete on each pointer in each column of the array that is pointing to a
    //row array of int's
    delete [] maxc[i];  
}

//call delete on the pointer pointing to the column of 
//the array that contains the original int pointers that were
//pointing to each of the row arrays of int's
delete [] maxc;
  

Ответ №3:

У вас могут возникнуть проблемы с корректным получением объявлений, но ваша реальная проблема заключается не в использовании стандартных контейнеров для выполнения работы за вас.

Этот код:

   int **  maxc = new int *[proc_num];//memory allocated for elements of rows
  for (int i = 0; i < proc_num; i  )
  {
        maxc[i] = new int*[n];//memory allocated for  elements of each column.
  }
  

Это можно исправить, чтобы заставить его компилироваться.

   int **  maxc = new int *[proc_num];
  for (int i = 0; i < proc_num; i  )
  {
        maxc[i] = new int[n];
             //     ^^^^ Note no star here.
  }
  

Но это все равно плохой код, поскольку вы не принимаете во внимание исключения (этот код будет утекать, если какое-либо выделение завершится неудачей). Во время использования, если ваш код генерирует исключение, вы потеряете всю память.

Лучшим решением было бы:

 std::vector<std::vector<int> >  maxc(proc_num, std::vector<int>(n, 0)); // even initializes all elements to 0
  

Если вы хотите пофантазировать, найдите многомерный массив boost, это может дать вам некоторые небольшие улучшения производительности (если вы выполняете умножение матриц и т.д.).

если вы действительно хотите сделать это вручную, тогда я бы начал изучать классы и RAII.

Ответ №4:

Это:

 int main() {
    int proc_num = 100;
    int n = 42;
    int **  maxc = new int *[proc_num];//memory allocated for elements of rows
    for (int i = 0; i < proc_num; i  ) {
            maxc[i] = new int[n];//memory allocated for  elements of each column.
    }
}
  

для меня компилируется просто отлично.

Комментарии:

1. int proc_num = 0; int n = 0; //Пользователь предоставляет значения для proc_num и n во время выполнения int ** maxc = new int *[proc_num];//память, выделенная для элементов строк для (int i = 0; i < proc_num; i ) { maxc[i] = new int[n];//память, выделенная для элементов каждого столбца. }