[C++] Passaggio di puntatori non consentito?

giuscri
Buongiorno ragazzi,

posto un codice semplice e d'esempio per chiedervi cosa mi manca dal punto di vista teorico per capire la cosa seguente:

ho un programmino che usando l'operatore new alloca variabili interere sullo heap.

Classico:

int
main()
{
  int N = 10;
  int* v = new int[N];

  int i;
  i = 0;
  while(i < 50)
  {
   v[i] = i;
   ++i;

   if(i == N)
    {
     int* noveau_v = new int[2*N];
     int j;
     for(j = 0; j < N; ++j)
     {
      noveau_v[j] = v[j]; 
     }

     delete[] v;
     v = noveau_v;
     N *= 2;
    }
  }
  return 0;
}


Cosa m'impedisce di allocare memoria sullo heap da una funzione che non sia la main? Il seguente codice viene compilato (da GCC) ma eseguendolo ricevo una serie di errori che faccio fatica a decodificare (li riporto in basso, nello spoiler):


// Function `stretch` should take as input
// a pointer to a contiguos area of memory
// in the heap, allocating a new contiguos
// area of memory, copy the content of the
// old area of memory, then deleting it, and make
// the old pointer pointing to the new continuguos
// area of memory:
void stretch(int* v, int& N);

int
main()
{
  int N = 10;
  int* v = new int[N];

  int i;
  i = 0;
  while(i < 50)
  {
   v[i] = i;
   ++i;

   if(i == N)
    {
     stretch(v, N);
    }
  }
  return 0;
}

void stretch(int* v, int& N)
{
  int* noveau_v = new int[2*N];
 
  int j;
  for(j = 0; j < N; ++j)
  { 
   noveau_v[j] = v[j];
   // delete (v +j);
   // That should be equivalent to `delete[] v`,
   // written outside the for-statement.
  }

  delete [] v;
  v = noveau_v;
  N *= 2;
  return;
}




Qualche hint? Cosa mi sfugge?

Risposte
claudio862
void stretch(int* v, int& N)
{
    ...
    v = noveau_v; // Invisible al di fuori di questa funzione,
                  // In particolare invisibile al main()
    N *= 2;
    return;
}

v è una variabile locale alla funzione stretch(), passata per valore. Di conseguenza, quando l'esecuzione torna alla funzione main(), il valore di v non è cambiato. Però la memoria puntata da v è stata liberata con l'operatore delete[] dentro stretch(), quindi non è più un puntatore valido (che è l'errore che hai quando probabilmente tenti di chiamare delete[] per la seconda volta). La soluzione è passare v per riferimento.

void stretch(int*& v, int& N)


Inoltre:

    // delete (v + j);
    // That should NOT be equivalent to `delete[] v`

    // v[j] equivale a *(v + j), quindi
    // (v + j) equivale a &v[j]

    delete [] v; // Libera l'*array* v
    delete &v[j] // Libera l'*elemento* alla posizione j
                 // (in questo caso è un errore perché tale elemento non è
                 // un puntatore a cui è stato assegnato un valore con new)

vict85
[OT]
Elementi contigui si traduce in “Contiguous elements”. L'ho notato solo perché Eclipse penso abbia il correttore ortografico incorporato :roll: .
[/OT]

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.