Bloques de memoria en C++ [Duda de Concepto]

Iniciado por tmb90, 9 Septiembre 2014, 21:29 PM

0 Miembros y 2 Visitantes están viendo este tema.

tmb90

Hola tengo una pregunta.

Para guardar cierta cantidad de bytes en la memoria de mi ordenador utilizo la memoria dinámica y hago lo siguiente.

char * bloque;
bloque = new char[cantbytes];

Quisiera saber por qué tengo que  definir a "bloque" como un puntero.

rir3760

Cita de: tmb90 en  9 Septiembre 2014, 21:29 PMQuisiera saber por qué tengo que  definir a "bloque" como un puntero.
Porque el resultado del operador new es la dirección en memoria donde se localiza el objeto creado (en tu caso un array de "cantbytes" caracteres), esa dirección se debe almacenar en una variable de tipo puntero porque en C y C++ "puntero" es el termino técnico para "dirección en memoria".

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

tmb90

¿Entonces por qué cuando le asigno los bytes a mi bloque no lo hago así: ?

file.read(*bloque, size);

en lugar de tener que hacerlo así:

file.read(bloque, size);

rir3760

Porque el primer argumento de la función miembro read es la dirección en memoria de (un puntero a) el bloque y el segundo el numero de caracteres a leer.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

kaiserr

Cita de: rir3760 en 10 Septiembre 2014, 02:59 AM
Porque el primer argumento de la función miembro read es la dirección en memoria de (un puntero a) el bloque y el segundo el numero de caracteres a leer.

Un saludo

Es decir, como ya has definido bloque como un puntero, no le tienes que volver a decir que es un puntero.
Si hicieras esto --> *bloque
Equivaldria a esto --> **bloque

Eternal Idol

*bloque no equivale a **bloque, *bloque es una indireccion valida y **bloque no ya que bloque no es un doble puntero. El Operador de desreferencia no dice que algo es un puntero.

Esto file.read(*bloque, size); no corresponde ya que le pasaria un CARACTER al metodo read (el primero) y es equivalente a file.read(bloque[0], size);, como ya te explico correctamente rir3760 el metodo en cuestion no recibe un caracter sino un puntero a caracter y esto es asi para poder modificar el bloque de memoria (si le pasas un caracter y no una direccion no puede adivinar donde poner el resultado de la lectura).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kaiserr

mmmmm pero yo me referia a que si a la funcion le pasas *bloque , es como si estuvieras pasandole **bloque... porque bloque ya esta definido como *bloque, no se si me explico.

Quizas la palabra equivale estaba mal puesta ahi, mejor decir es como...
Si sigo equivocado corregirme :) :-X

Eternal Idol

No, no entiendo que queres explicar y sospecho que no leiste el enlace que deje sobre el operador de desreferencia. Si la variable no fuera un puntero (char bloque) no la podrias desreferenciar ... y como no es un doble puntero no la podes desrefenciar dos veces.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

eferion

Si tenemos 'char** bloque', entonces:


  • 'bloque' es un puntero doble a char
  • '*bloque' es un puntero a char
  • '**bloque' es un char

Se ve entonces claramente que '*bloque' no es lo mismo que '**bloque'

Ejemplo 1:


void funcionInutil( char bloque )
{
  bloque = 'a';
}

void funcionUtil( char* bloque )
{
  *bloque = 'a';
}

int main( )
{
  char bloque = '0';

  funcionInutil( bloque );
  printf( "%c", bloque );

  funcionUtil( &bloque );
  printf( "%c", bloque );
}


Ejemplo 2:


void funcionInutil( char *bloque )
{
  bloque = malloc( 20, 1 );

  // Imprime la dirección de memoria que acaba de reservar
  printf( "%d\n", bloque );
}

void funcionUtil( char **bloque )
{
  *bloque = malloc( 20, 1 );

  // Imprime la dirección de memoria que acaba de reservar
  printf( "%d\n", *bloque );
}

int main( )
{
  char *bloque = NULL;

  funcionInutil( bloque );

  // Imprimirá 0, 'bloque' se ha pasado por copia, luego su valor no se puede modificar
  printf( "%d\n", bloque );

  funcionUtil( &bloque );

  // Ahora si se ha podido modificar 'bloque' porque se ha pasado por referencia.
  printf( "%d\n", bloque );
}


Espero que con estos ejemplos quede un poco más claro el tema de los punteros, las referencias y las desreferencias.

kaiserr

Cita de: Eternal Idol en 11 Septiembre 2014, 10:18 AM
No, no entiendo que queres explicar y sospecho que no leiste el enlace que deje sobre el operador de desreferencia. Si la variable no fuera un puntero (char bloque) no la podrias desreferenciar ... y como no es un doble puntero no la podes desrefenciar dos veces.

si lo lei  :) y entiendo el funcionamiento de los operadores de desferencia (quizas no tan bien como otros), pero a lo que yo me referia es:
Si se declara char *bloque; y luego una funcion necesita que se le pase un puntero:
read(bloque)
Hasta aqui bien no?
Pero si le pasamos por error read(*bloque), teniendo char *bloque... no seria lo mismo que tener char **bloque y pasarle read(bloque)
:-X