Dani | 22 Apr 2012 17:43

Diferencia entre *p=*p y memcpy

¡Buenas a todos!

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

*p=*j;
memcpy(p, j  , sizeof(struct q));

Espero que alguien me pueda sacar de la duda.
Gracias.
<div>&iexcl;Buenas a todos!<div><br></div>
<div>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</div>

<div><br></div>
<div>*p=*j;</div>
<div>memcpy(<span>p,&nbsp;</span><span>j &nbsp;, sizeof(struct q));</span>
</div>

<div><br></div>
<div>Espero que alguien me pueda sacar de la duda.</div>
<div>Gracias.</div>
</div>
Miguel Angel | 22 Apr 2012 19:10
Picon
Gravatar

Re: Diferencia entre *p=*p y memcpy

Hola!!


Para entenderlo bien, lo suyo es que comprendas cómo funciona un puntero.

Básicamente, cuando tienes un puntero que apunta a una estructura, estás guardando datos en dos sitios: por una parte, el puntero es una dirección de memoria, que se guardará en el Heap; por otro, la estructura estará almacenada en la posición de memoria, en el Stack.

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrarán en el Heap, y la propia estructura, que estará en el Stack.

Cuando utilizas memcpy, lo que estás haciendo es realizar una copia de la posición de memoria (el Stack) en otro sitio(también en el Stack). Ten cuidado, porque memcpy no reservará esa memoria.

Si comprendes la diferencia entre el Heap y el Stack, todo es más sencillo. Cuando haces:
  • int i;
  • void* pointer;
etc, estás reservando memoria en el Heap. Ésta es volátil y la suele gestionar el propio compilador.

Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) estás usando el Stack, y eres tú el encargado de gestionar su liberación.

Por eso, cuando usas: "*p = *j", estás utilizando sólo el Heap. Cuando usas "strcpy", estás leyendo y escribiendo en el Stack.

Espero haberme explicado. Un saludo!!

El 22 de abril de 2012 17:43, Dani <dani <at> azthe.com> escribió:
¡Buenas a todos!

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

*p=*j;
memcpy(p, j  , sizeof(struct q));

Espero que alguien me pueda sacar de la duda.
Gracias.

_______________________________________________
CRySoL mailing list
http://crysol.org/
https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol




--
Miguel Ángel García Martínez
<div>
<p>Hola!!</p>
<div><br></div>
<div>Para entenderlo bien, lo suyo es que comprendas c&oacute;mo funciona un puntero.</div>
<div><br></div>
<div>B&aacute;sicamente, cuando tienes un puntero que apunta a una estructura, est&aacute;s guardando datos en dos sitios: por una parte, el puntero es una direcci&oacute;n de memoria, que se guardar&aacute; en el Heap; por otro, la estructura estar&aacute; almacenada en la posici&oacute;n de memoria, en el Stack.</div>
<div><br></div>
<div>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrar&aacute;n en el Heap, y la propia estructura, que estar&aacute; en el Stack.</div>
<div><br></div>
<div>Cuando utilizas memcpy, lo que est&aacute;s haciendo es realizar una copia de la posici&oacute;n de memoria (el Stack) en otro sitio(tambi&eacute;n en el Stack). Ten cuidado, porque memcpy no reservar&aacute; esa memoria.</div>
<div>
<br>
</div>
<div>Si comprendes la diferencia entre el Heap y el Stack, todo es m&aacute;s sencillo. Cuando haces:</div>
<div>
<ul>
<li>int i;</li>
<li>void* pointer;</li>
</ul>
<div>etc, est&aacute;s reservando memoria en el Heap. &Eacute;sta es vol&aacute;til y la suele gestionar el propio compilador.</div>
</div>
<div><br></div>
<div>Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) est&aacute;s usando el Stack, y eres t&uacute; el encargado de gestionar su liberaci&oacute;n.</div>
<div><br></div>
<div>Por eso, cuando usas: "*p = *j", est&aacute;s utilizando s&oacute;lo el Heap. Cuando usas "strcpy", est&aacute;s leyendo y escribiendo en el Stack.</div>
<div>
<br>Pint&aacute;ndolo:&nbsp;<a href="http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C">http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C</a>
</div>
<div>Diferencias entre el Heap y el Stack:&nbsp;<a href="http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory">http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory</a>
</div>
<div><br></div>
<div>Espero haberme explicado. Un saludo!!<br><br><div class="gmail_quote">El 22 de abril de 2012 17:43, Dani <span dir="ltr">&lt;<a href="mailto:dani <at> azthe.com">dani <at> azthe.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">
&iexcl;Buenas a todos!<div><br></div>
<div>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</div>

<div><br></div>
<div>*p=*j;</div>
<div>memcpy(<span>p,&nbsp;</span><span>j &nbsp;, sizeof(struct q));</span>
</div>

<div><br></div>
<div>Espero que alguien me pueda sacar de la duda.</div>
<div>Gracias.</div>

<br>_______________________________________________<br>
CRySoL mailing list<br><a href="http://crysol.org/" target="_blank">http://crysol.org/</a><br><a href="https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol" target="_blank">https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol</a><br><br>
</blockquote>
</div>
<br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>
<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br>
</div>
</div>
Dani | 22 Apr 2012 20:39

Re: Diferencia entre *p=*p y memcpy

Gracias Miguel Ángel por haberte tomado el tiempo de explicármelo. 

Pero solo tengo una pregunta más, cuando dices:

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria.

¿Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, creía que cuando se hacía la operación *p=*j, imaginando que son enteros, ¿no se crea una nueva posición de memoria? Es decir, que si modifico j, no cambiaría el valor de p;

Saludos.

El 22 de abril de 2012 19:10, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:
Hola!!

Para entenderlo bien, lo suyo es que comprendas cómo funciona un puntero.

Básicamente, cuando tienes un puntero que apunta a una estructura, estás guardando datos en dos sitios: por una parte, el puntero es una dirección de memoria, que se guardará en el Heap; por otro, la estructura estará almacenada en la posición de memoria, en el Stack.

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrarán en el Heap, y la propia estructura, que estará en el Stack.

Cuando utilizas memcpy, lo que estás haciendo es realizar una copia de la posición de memoria (el Stack) en otro sitio(también en el Stack). Ten cuidado, porque memcpy no reservará esa memoria.

Si comprendes la diferencia entre el Heap y el Stack, todo es más sencillo. Cuando haces:
  • int i;
  • void* pointer;
etc, estás reservando memoria en el Heap. Ésta es volátil y la suele gestionar el propio compilador.

Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) estás usando el Stack, y eres tú el encargado de gestionar su liberación.

Por eso, cuando usas: "*p = *j", estás utilizando sólo el Heap. Cuando usas "strcpy", estás leyendo y escribiendo en el Stack.

Espero haberme explicado. Un saludo!!

El 22 de abril de 2012 17:43, Dani <dani <at> azthe.com> escribió:
¡Buenas a todos!

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

*p=*j;
memcpy(p, j  , sizeof(struct q));

Espero que alguien me pueda sacar de la duda.
Gracias.

_______________________________________________
CRySoL mailing list
http://crysol.org/
https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol




--
Miguel Ángel García Martínez

<div>
<div class="gmail_extra"><span>Gracias Miguel &Aacute;ngel por haberte tomado el tiempo de explic&aacute;rmelo.&nbsp;</span></div>
<div class="gmail_extra"><span><br></span></div>
<div class="gmail_extra"><span>Pero solo tengo una pregunta m&aacute;s, cuando dices:</span></div>
<div class="gmail_extra"><span><br></span></div>
<div class="gmail_extra">
<span>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria.</span><br><br>&iquest;Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, cre&iacute;a que cuando se hac&iacute;a la operaci&oacute;n *p=*j, imaginando que son enteros, &iquest;no se crea una nueva posici&oacute;n de memoria? Es decir, que si modifico j, no cambiar&iacute;a el valor de p;</div>
<div class="gmail_extra"><br></div>
<div class="gmail_extra">Saludos.</div>
<div class="gmail_extra">
<br><div class="gmail_quote">El 22 de abril de 2012 19:10, Miguel Angel <span dir="ltr">&lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">Hola!!<div><br></div>
<div>Para entenderlo bien, lo suyo es que comprendas c&oacute;mo funciona un puntero.</div>
<div><br></div>
<div>B&aacute;sicamente, cuando tienes un puntero que apunta a una estructura, est&aacute;s guardando datos en dos sitios: por una parte, el puntero es una direcci&oacute;n de memoria, que se guardar&aacute; en el Heap; por otro, la estructura estar&aacute; almacenada en la posici&oacute;n de memoria, en el Stack.</div>

<div><br></div>
<div>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrar&aacute;n en el Heap, y la propia estructura, que estar&aacute; en el Stack.</div>

<div><br></div>
<div>Cuando utilizas memcpy, lo que est&aacute;s haciendo es realizar una copia de la posici&oacute;n de memoria (el Stack) en otro sitio(tambi&eacute;n en el Stack). Ten cuidado, porque memcpy no reservar&aacute; esa memoria.</div>
<div>

<br>
</div>
<div>Si comprendes la diferencia entre el Heap y el Stack, todo es m&aacute;s sencillo. Cuando haces:</div>
<div>
<ul>
<li>int i;</li>
<li>void* pointer;</li>
</ul>
<div>etc, est&aacute;s reservando memoria en el Heap. &Eacute;sta es vol&aacute;til y la suele gestionar el propio compilador.</div>

</div>
<div><br></div>
<div>Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) est&aacute;s usando el Stack, y eres t&uacute; el encargado de gestionar su liberaci&oacute;n.</div>
<div><br></div>
<div>Por eso, cuando usas: "*p = *j", est&aacute;s utilizando s&oacute;lo el Heap. Cuando usas "strcpy", est&aacute;s leyendo y escribiendo en el Stack.</div>

<div>
<br>Pint&aacute;ndolo:&nbsp;<a href="http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C" target="_blank">http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C</a>
</div>
<div>Diferencias entre el Heap y el Stack:&nbsp;<a href="http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory" target="_blank">http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory</a>
</div>

<div><br></div>
<div>Espero haberme explicado. Un saludo!!<br><br><div class="gmail_quote">El 22 de abril de 2012 17:43, Dani <span dir="ltr">&lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">
<div><div class="h5">
&iexcl;Buenas a todos!<div><br></div>
<div>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</div>

<div><br></div>
<div>*p=*j;</div>
<div>memcpy(<span>p,&nbsp;</span><span>j &nbsp;, sizeof(struct q));</span>
</div>

<div><br></div>
<div>Espero que alguien me pueda sacar de la duda.</div>
<div>Gracias.</div>

<br>
</div></div>_______________________________________________<br>
CRySoL mailing list<br><a href="http://crysol.org/" target="_blank">http://crysol.org/</a><br><a href="https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol" target="_blank">https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol</a><br><br>
</blockquote>
</div>
<span class="HOEnZb"><br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>
<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br></span>
</div>
</blockquote>
</div>
<br>
</div>
</div>
Miguel Angel | 22 Apr 2012 21:37
Picon
Gravatar

Re: Diferencia entre *p=*p y memcpy

Tienes que diferenciar entre la posición de memoria en la que se almacenan las variables y la dirección a la que apuntan. De esta manera, la posición de memoria en la que se encuentra "p" contiene, exactamente, la posición de memoria de "*p".


Y debería aplicarme el cuento, ya que me equivoqué :D

Cuando usas "*p = *j" estás diciendo: allí donde apunta p, guarda lo que apunta j". Pero como una imagen vale más que mil palabras, te mando la imagen (punteros.png).

Te invito a que tú también utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 años, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).

Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D

El código es el siguiente:
int main()
{
  int value = 5;

  int* a;
  int* b;

  int* j;
  int* k;

  a = &value;
  b = a;

  j = &value;
  *k = *j;


  return 0;
}

Sin embargo, con este código sí que sería válido:
int main()
{
  int value = 5;

  int* a;
  int* b;

  int** j;
  int** k;

  a = &value;

  j = &a;
  k = &b;
  *k = *j;

  return 0;
}

Como verás, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).

En fin... espero haberlo explicado bien (ahora sí) :D

Un saludo!

El 22 de abril de 2012 20:39, Dani <dani <at> azthe.com> escribió:
Gracias Miguel Ángel por haberte tomado el tiempo de explicármelo. 

Pero solo tengo una pregunta más, cuando dices:

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria.

¿Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, creía que cuando se hacía la operación *p=*j, imaginando que son enteros, ¿no se crea una nueva posición de memoria? Es decir, que si modifico j, no cambiaría el valor de p;

Saludos.

El 22 de abril de 2012 19:10, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:

Hola!!

Para entenderlo bien, lo suyo es que comprendas cómo funciona un puntero.

Básicamente, cuando tienes un puntero que apunta a una estructura, estás guardando datos en dos sitios: por una parte, el puntero es una dirección de memoria, que se guardará en el Heap; por otro, la estructura estará almacenada en la posición de memoria, en el Stack.

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrarán en el Heap, y la propia estructura, que estará en el Stack.

Cuando utilizas memcpy, lo que estás haciendo es realizar una copia de la posición de memoria (el Stack) en otro sitio(también en el Stack). Ten cuidado, porque memcpy no reservará esa memoria.

Si comprendes la diferencia entre el Heap y el Stack, todo es más sencillo. Cuando haces:
  • int i;
  • void* pointer;
etc, estás reservando memoria en el Heap. Ésta es volátil y la suele gestionar el propio compilador.

Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) estás usando el Stack, y eres tú el encargado de gestionar su liberación.

Por eso, cuando usas: "*p = *j", estás utilizando sólo el Heap. Cuando usas "strcpy", estás leyendo y escribiendo en el Stack.

Espero haberme explicado. Un saludo!!

El 22 de abril de 2012 17:43, Dani <dani <at> azthe.com> escribió:
¡Buenas a todos!

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

*p=*j;
memcpy(p, j  , sizeof(struct q));

Espero que alguien me pueda sacar de la duda.
Gracias.

_______________________________________________
CRySoL mailing list
http://crysol.org/
https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol




--
Miguel Ángel García Martínez




--
Miguel Ángel García Martínez
<div>
<p>Tienes que diferenciar entre la posici&oacute;n de memoria en la que se almacenan las variables y la direcci&oacute;n a la que apuntan. De esta manera, la posici&oacute;n de memoria en la que se encuentra "p" contiene, exactamente, la posici&oacute;n de memoria de "*p".</p>
<div>
<br>
</div>
<div>Y deber&iacute;a aplicarme el cuento, ya que me equivoqu&eacute; :D</div>
<div><br></div>
<div>Cuando usas "*p = *j" est&aacute;s diciendo: all&iacute; donde apunta p, guarda lo que apunta j". Pero como una imagen vale m&aacute;s que mil palabras, te mando la imagen (punteros.png).</div>
<div><br></div>
<div>Te invito a que t&uacute; tambi&eacute;n utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 a&ntilde;os, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).</div>
<div><br></div>
<div>Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D</div>
<div><br></div>
<div>El c&oacute;digo es el siguiente:</div>
<div><blockquote>
<div>
<div>int main()</div>
<div>{</div>
<div>&nbsp; int value = 5;</div>
<div><br></div>
<div>&nbsp; int* a;</div>
<div>&nbsp; int* b;</div>
<div><br></div>
<div>&nbsp; int* j;</div>
<div>&nbsp; int* k;</div>
<div><br></div>
<div>&nbsp; a = &amp;value;</div>
<div>
&nbsp; b = a;</div>
<div><br></div>
<div>&nbsp; j = &amp;value;</div>
<div>&nbsp; *k = *j;</div>
<div><br></div>
<div><br></div>
<div>&nbsp; return 0;</div>
<div>}</div>
</div>
</blockquote></div>
<div><br></div>
<div>Sin embargo, con este c&oacute;digo s&iacute; que ser&iacute;a v&aacute;lido:</div>
<div><blockquote><div>
<div>int main()</div>
<div>{</div>
<div>&nbsp; int value = 5;</div>
<div><br></div>
<div>&nbsp; int* a;</div>
<div>&nbsp; int* b;</div>
<div><br></div>
<div>&nbsp; int** j;</div>
<div>&nbsp; int** k;</div>
<div><br></div>
<div>&nbsp; a = &amp;value;</div>
<div><br></div>
<div>&nbsp; j = &amp;a;</div>
<div>&nbsp; k = &amp;b;</div>
<div>&nbsp; *k = *j;</div>
<div><br></div>
<div>&nbsp; return 0;</div>
<div>}</div>
</div></blockquote></div>
<div>
<br><div>Como ver&aacute;s, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).</div>
<div><br></div>
<div>En fin... espero haberlo explicado bien (ahora s&iacute;) :D</div>
<div><br></div>
<div>Un saludo!</div>
<div>
<br><div class="gmail_quote">El 22 de abril de 2012 20:39, Dani <span dir="ltr">&lt;<a href="mailto:dani <at> azthe.com">dani <at> azthe.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">
<div class="gmail_extra"><span>Gracias Miguel &Aacute;ngel por haberte tomado el tiempo de explic&aacute;rmelo.&nbsp;</span></div>
<div class="gmail_extra"><span><br></span></div>
<div class="gmail_extra"><span>Pero solo tengo una pregunta m&aacute;s, cuando dices:</span></div>

<div class="gmail_extra"><span><br></span></div>
<div class="gmail_extra">
<div class="im">
<span>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria.</span><br><br>
</div>&iquest;Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, cre&iacute;a que cuando se hac&iacute;a la operaci&oacute;n *p=*j, imaginando que son enteros, &iquest;no se crea una nueva posici&oacute;n de memoria? Es decir, que si modifico j, no cambiar&iacute;a el valor de p;</div>

<div class="gmail_extra"><br></div>
<div class="gmail_extra">Saludos.</div>
<div class="gmail_extra">
<br><div class="gmail_quote">El 22 de abril de 2012 19:10, Miguel Angel <span dir="ltr">&lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt;</span> escribi&oacute;:<div>
<div class="h5">
<br><blockquote class="gmail_quote">Hola!!<div><br></div>
<div>Para entenderlo bien, lo suyo es que comprendas c&oacute;mo funciona un puntero.</div>
<div><br></div>

<div>B&aacute;sicamente, cuando tienes un puntero que apunta a una estructura, est&aacute;s guardando datos en dos sitios: por una parte, el puntero es una direcci&oacute;n de memoria, que se guardar&aacute; en el Heap; por otro, la estructura estar&aacute; almacenada en la posici&oacute;n de memoria, en el Stack.</div>

<div><br></div>
<div>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrar&aacute;n en el Heap, y la propia estructura, que estar&aacute; en el Stack.</div>

<div><br></div>
<div>Cuando utilizas memcpy, lo que est&aacute;s haciendo es realizar una copia de la posici&oacute;n de memoria (el Stack) en otro sitio(tambi&eacute;n en el Stack). Ten cuidado, porque memcpy no reservar&aacute; esa memoria.</div>
<div>

<br>
</div>
<div>Si comprendes la diferencia entre el Heap y el Stack, todo es m&aacute;s sencillo. Cuando haces:</div>
<div>
<ul>
<li>int i;</li>
<li>void* pointer;</li>
</ul>
<div>etc, est&aacute;s reservando memoria en el Heap. &Eacute;sta es vol&aacute;til y la suele gestionar el propio compilador.</div>

</div>
<div><br></div>
<div>Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) est&aacute;s usando el Stack, y eres t&uacute; el encargado de gestionar su liberaci&oacute;n.</div>
<div><br></div>
<div>Por eso, cuando usas: "*p = *j", est&aacute;s utilizando s&oacute;lo el Heap. Cuando usas "strcpy", est&aacute;s leyendo y escribiendo en el Stack.</div>

<div>
<br>Pint&aacute;ndolo:&nbsp;<a href="http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C" target="_blank">http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C</a>
</div>
<div>Diferencias entre el Heap y el Stack:&nbsp;<a href="http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory" target="_blank">http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory</a>
</div>

<div><br></div>
<div>Espero haberme explicado. Un saludo!!<br><br><div class="gmail_quote">El 22 de abril de 2012 17:43, Dani <span dir="ltr">&lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">
<div><div>
&iexcl;Buenas a todos!<div><br></div>
<div>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</div>

<div><br></div>
<div>*p=*j;</div>
<div>memcpy(<span>p,&nbsp;</span><span>j &nbsp;, sizeof(struct q));</span>
</div>

<div><br></div>
<div>Espero que alguien me pueda sacar de la duda.</div>
<div>Gracias.</div>

<br>
</div></div>_______________________________________________<br>
CRySoL mailing list<br><a href="http://crysol.org/" target="_blank">http://crysol.org/</a><br><a href="https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol" target="_blank">https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol</a><br><br>
</blockquote>
</div>
<span><br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>

<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br></span>
</div>
</blockquote>
</div>
</div>
</div>
<br>
</div>
</blockquote>
</div>
<br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>
<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br>
</div>
</div>
</div>
Dani | 22 Apr 2012 23:30

Re: Diferencia entre *p=*p y memcpy

¡Muchas gracias por todo! Lo has explicado muy bien y de paso, ahora entiendo por qué existen los ** XD 

Probaré DDD, a ver que tal se me da.

Saludos.

El 22 de abril de 2012 21:37, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:
Tienes que diferenciar entre la posición de memoria en la que se almacenan las variables y la dirección a la que apuntan. De esta manera, la posición de memoria en la que se encuentra "p" contiene, exactamente, la posición de memoria de "*p".

Y debería aplicarme el cuento, ya que me equivoqué :D

Cuando usas "*p = *j" estás diciendo: allí donde apunta p, guarda lo que apunta j". Pero como una imagen vale más que mil palabras, te mando la imagen (punteros.png).

Te invito a que tú también utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 años, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).

Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D

El código es el siguiente:
int main()
{
  int value = 5;

  int* a;
  int* b;

  int* j;
  int* k;

  a = &value;
  b = a;

  j = &value;
  *k = *j;


  return 0;
}

Sin embargo, con este código sí que sería válido:
int main()
{
  int value = 5;

  int* a;
  int* b;

  int** j;
  int** k;

  a = &value;

  j = &a;
  k = &b;
  *k = *j;

  return 0;
}

Como verás, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).

En fin... espero haberlo explicado bien (ahora sí) :D

Un saludo!

El 22 de abril de 2012 20:39, Dani <dani <at> azthe.com> escribió:

Gracias Miguel Ángel por haberte tomado el tiempo de explicármelo. 

Pero solo tengo una pregunta más, cuando dices:

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria.

¿Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, creía que cuando se hacía la operación *p=*j, imaginando que son enteros, ¿no se crea una nueva posición de memoria? Es decir, que si modifico j, no cambiaría el valor de p;

Saludos.

El 22 de abril de 2012 19:10, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:

Hola!!

Para entenderlo bien, lo suyo es que comprendas cómo funciona un puntero.

Básicamente, cuando tienes un puntero que apunta a una estructura, estás guardando datos en dos sitios: por una parte, el puntero es una dirección de memoria, que se guardará en el Heap; por otro, la estructura estará almacenada en la posición de memoria, en el Stack.

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrarán en el Heap, y la propia estructura, que estará en el Stack.

Cuando utilizas memcpy, lo que estás haciendo es realizar una copia de la posición de memoria (el Stack) en otro sitio(también en el Stack). Ten cuidado, porque memcpy no reservará esa memoria.

Si comprendes la diferencia entre el Heap y el Stack, todo es más sencillo. Cuando haces:
  • int i;
  • void* pointer;
etc, estás reservando memoria en el Heap. Ésta es volátil y la suele gestionar el propio compilador.

Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) estás usando el Stack, y eres tú el encargado de gestionar su liberación.

Por eso, cuando usas: "*p = *j", estás utilizando sólo el Heap. Cuando usas "strcpy", estás leyendo y escribiendo en el Stack.

Espero haberme explicado. Un saludo!!

El 22 de abril de 2012 17:43, Dani <dani <at> azthe.com> escribió:
¡Buenas a todos!

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

*p=*j;
memcpy(p, j  , sizeof(struct q));

Espero que alguien me pueda sacar de la duda.
Gracias.

_______________________________________________
CRySoL mailing list
http://crysol.org/
https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol




--
Miguel Ángel García Martínez




--
Miguel Ángel García Martínez

<div><div class="gmail_extra">
<div class="gmail_extra">&iexcl;Muchas gracias por todo! Lo has explicado muy bien y de paso, ahora entiendo por qu&eacute; existen los ** XD&nbsp;</div>
<div class="gmail_extra"><br></div>
<div class="gmail_extra">
Probar&eacute; DDD, a ver que tal se me da.</div>
<div class="gmail_extra"><br></div>
<div class="gmail_extra">Saludos.</div>
<br><div class="gmail_quote">El 22 de abril de 2012 21:37, Miguel Angel <span dir="ltr">&lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">Tienes que diferenciar entre la posici&oacute;n de memoria en la que se almacenan las variables y la direcci&oacute;n a la que apuntan. De esta manera, la posici&oacute;n de memoria en la que se encuentra "p" contiene, exactamente, la posici&oacute;n de memoria de "*p".<div>

<br>
</div>
<div>Y deber&iacute;a aplicarme el cuento, ya que me equivoqu&eacute; :D</div>
<div><br></div>
<div>Cuando usas "*p = *j" est&aacute;s diciendo: all&iacute; donde apunta p, guarda lo que apunta j". Pero como una imagen vale m&aacute;s que mil palabras, te mando la imagen (punteros.png).</div>

<div><br></div>
<div>Te invito a que t&uacute; tambi&eacute;n utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 a&ntilde;os, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).</div>

<div><br></div>
<div>Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D</div>
<div><br></div>
<div>El c&oacute;digo es el siguiente:</div>
<div><blockquote>

<div>
<div>int main()</div>
<div>{</div>
<div>&nbsp; int value = 5;</div>
<div><br></div>
<div>&nbsp; int* a;</div>
<div>&nbsp; int* b;</div>
<div><br></div>
<div>&nbsp; int* j;</div>
<div>&nbsp; int* k;</div>
<div><br></div>
<div>&nbsp; a = &amp;value;</div>
<div>

&nbsp; b = a;</div>
<div><br></div>
<div>&nbsp; j = &amp;value;</div>
<div>&nbsp; *k = *j;</div>
<div><br></div>
<div><br></div>
<div>&nbsp; return 0;</div>
<div>}</div>
</div>
</blockquote></div>
<div><br></div>
<div>Sin embargo, con este c&oacute;digo s&iacute; que ser&iacute;a v&aacute;lido:</div>

<div><blockquote><div>
<div>int main()</div>
<div>{</div>
<div>&nbsp; int value = 5;</div>
<div><br></div>
<div>&nbsp; int* a;</div>
<div>&nbsp; int* b;</div>
<div><br></div>
<div>&nbsp; int** j;</div>

<div>&nbsp; int** k;</div>
<div><br></div>
<div>&nbsp; a = &amp;value;</div>
<div><br></div>
<div>&nbsp; j = &amp;a;</div>
<div>&nbsp; k = &amp;b;</div>
<div>&nbsp; *k = *j;</div>
<div><br></div>
<div>&nbsp; return 0;</div>
<div>}</div>
</div></blockquote></div>

<div>
<br><div>Como ver&aacute;s, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).</div>
<div><br></div>
<div>En fin... espero haberlo explicado bien (ahora s&iacute;) :D</div>
<div><br></div>
<div>Un saludo!</div>

<div>
<br><div class="gmail_quote">El 22 de abril de 2012 20:39, Dani <span dir="ltr">&lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt;</span> escribi&oacute;:<div><div>
<br><blockquote class="gmail_quote">

<div class="gmail_extra"><span>Gracias Miguel &Aacute;ngel por haberte tomado el tiempo de explic&aacute;rmelo.&nbsp;</span></div>
<div class="gmail_extra"><span><br></span></div>
<div class="gmail_extra"><span>Pero solo tengo una pregunta m&aacute;s, cuando dices:</span></div>

<div class="gmail_extra"><span><br></span></div>
<div class="gmail_extra">
<div>
<span>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria.</span><br><br>
</div>&iquest;Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, cre&iacute;a que cuando se hac&iacute;a la operaci&oacute;n *p=*j, imaginando que son enteros, &iquest;no se crea una nueva posici&oacute;n de memoria? Es decir, que si modifico j, no cambiar&iacute;a el valor de p;</div>

<div class="gmail_extra"><br></div>
<div class="gmail_extra">Saludos.</div>
<div class="gmail_extra">
<br><div class="gmail_quote">El 22 de abril de 2012 19:10, Miguel Angel <span dir="ltr">&lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt;</span> escribi&oacute;:<div>

<div>
<br><blockquote class="gmail_quote">Hola!!<div><br></div>
<div>Para entenderlo bien, lo suyo es que comprendas c&oacute;mo funciona un puntero.</div>
<div><br></div>

<div>B&aacute;sicamente, cuando tienes un puntero que apunta a una estructura, est&aacute;s guardando datos en dos sitios: por una parte, el puntero es una direcci&oacute;n de memoria, que se guardar&aacute; en el Heap; por otro, la estructura estar&aacute; almacenada en la posici&oacute;n de memoria, en el Stack.</div>

<div><br></div>
<div>Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrar&aacute;n en el Heap, y la propia estructura, que estar&aacute; en el Stack.</div>

<div><br></div>
<div>Cuando utilizas memcpy, lo que est&aacute;s haciendo es realizar una copia de la posici&oacute;n de memoria (el Stack) en otro sitio(tambi&eacute;n en el Stack). Ten cuidado, porque memcpy no reservar&aacute; esa memoria.</div>
<div>

<br>
</div>
<div>Si comprendes la diferencia entre el Heap y el Stack, todo es m&aacute;s sencillo. Cuando haces:</div>
<div>
<ul>
<li>int i;</li>
<li>void* pointer;</li>
</ul>
<div>etc, est&aacute;s reservando memoria en el Heap. &Eacute;sta es vol&aacute;til y la suele gestionar el propio compilador.</div>

</div>
<div><br></div>
<div>Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) est&aacute;s usando el Stack, y eres t&uacute; el encargado de gestionar su liberaci&oacute;n.</div>
<div><br></div>
<div>Por eso, cuando usas: "*p = *j", est&aacute;s utilizando s&oacute;lo el Heap. Cuando usas "strcpy", est&aacute;s leyendo y escribiendo en el Stack.</div>

<div>
<br>Pint&aacute;ndolo:&nbsp;<a href="http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C" target="_blank">http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C</a>
</div>
<div>Diferencias entre el Heap y el Stack:&nbsp;<a href="http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory" target="_blank">http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory</a>
</div>

<div><br></div>
<div>Espero haberme explicado. Un saludo!!<br><br><div class="gmail_quote">El 22 de abril de 2012 17:43, Dani <span dir="ltr">&lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">
<div><div>
&iexcl;Buenas a todos!<div><br></div>
<div>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</div>

<div><br></div>
<div>*p=*j;</div>
<div>memcpy(<span>p,&nbsp;</span><span>j &nbsp;, sizeof(struct q));</span>
</div>

<div><br></div>
<div>Espero que alguien me pueda sacar de la duda.</div>
<div>Gracias.</div>

<br>
</div></div>_______________________________________________<br>
CRySoL mailing list<br><a href="http://crysol.org/" target="_blank">http://crysol.org/</a><br><a href="https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol" target="_blank">https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol</a><br><br>
</blockquote>
</div>
<span><br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>

<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br></span>
</div>
</blockquote>
</div>
</div>
</div>
<br>
</div>
</blockquote>
</div></div>
</div>
<div><div>
<br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>

<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br>
</div></div>
</div>
</div>
</blockquote>
</div>
<br>
</div></div>
JAVIER CHICO CESPEDES | 23 Apr 2012 00:08
Picon

Re: Diferencia entre *p=*p y memcpy

Buenas,

 

Cuando comentas lo del heap/stack, me surge la duda de si no es al revés (al menos así lo tenía yo interiorizado). Es decir, el stack es donde se almacenan las variables de una función y al retornar de la función se eliminan del stack y con operaciones malloc reservas memoria en el heap; que no es ni más ni menos que memoria paginada reservada por el SO para el proceso. Corresponde al proceso la liberación de las páginas reservadas en el heap.

 

Saludos!

 

De: crysol-bounces <at> arco.esi.uclm.es [mailto:crysol-bounces <at> arco.esi.uclm.es] En nombre de Dani
Enviado el: domingo, 22 de abril de 2012 23:31
Para: Miguel Angel
CC: Lista CRySoL
Asunto: Re: [CRySoL] Diferencia entre *p=*p y memcpy

 

¡Muchas gracias por todo! Lo has explicado muy bien y de paso, ahora entiendo por qué existen los ** XD 

 

Probaré DDD, a ver que tal se me da.

 

Saludos.

 

El 22 de abril de 2012 21:37, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:

Tienes que diferenciar entre la posición de memoria en la que se almacenan las variables y la dirección a la que apuntan. De esta manera, la posición de memoria en la que se encuentra "p" contiene, exactamente, la posición de memoria de "*p".

 

Y debería aplicarme el cuento, ya que me equivoqué :D

 

Cuando usas "*p = *j" estás diciendo: allí donde apunta p, guarda lo que apunta j". Pero como una imagen vale más que mil palabras, te mando la imagen (punteros.png).

 

Te invito a que tú también utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 años, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).

 

Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D

 

El código es el siguiente:

int main()

{

  int value = 5;

 

  int* a;

  int* b;

 

  int* j;

  int* k;

 

  a = &value;

  b = a;

 

  j = &value;

  *k = *j;

 

 

  return 0;

}

 

Sin embargo, con este código sí que sería válido:

int main()

{

  int value = 5;

 

  int* a;

  int* b;

 

  int** j;

  int** k;

 

  a = &value;

 

  j = &a;

  k = &b;

  *k = *j;

 

  return 0;

}

 

Como verás, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).

 

En fin... espero haberlo explicado bien (ahora sí) :D

 

Un saludo!

 

El 22 de abril de 2012 20:39, Dani <dani <at> azthe.com> escribió:

 

Gracias Miguel Ángel por haberte tomado el tiempo de explicármelo. 

 

Pero solo tengo una pregunta más, cuando dices:

 

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria.

¿Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, creía que cuando se hacía la operación *p=*j, imaginando que son enteros, ¿no se crea una nueva posición de memoria? Es decir, que si modifico j, no cambiaría el valor de p;

 

Saludos.

 

El 22 de abril de 2012 19:10, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:

 

Hola!!

 

Para entenderlo bien, lo suyo es que comprendas cómo funciona un puntero.

 

Básicamente, cuando tienes un puntero que apunta a una estructura, estás guardando datos en dos sitios: por una parte, el puntero es una dirección de memoria, que se guardará en el Heap; por otro, la estructura estará almacenada en la posición de memoria, en el Stack.

 

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrarán en el Heap, y la propia estructura, que estará en el Stack.

 

Cuando utilizas memcpy, lo que estás haciendo es realizar una copia de la posición de memoria (el Stack) en otro sitio(también en el Stack). Ten cuidado, porque memcpy no reservará esa memoria.

 

Si comprendes la diferencia entre el Heap y el Stack, todo es más sencillo. Cuando haces:

  • int i;

  • void* pointer;

etc, estás reservando memoria en el Heap. Ésta es volátil y la suele gestionar el propio compilador.

 

Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) estás usando el Stack, y eres tú el encargado de gestionar su liberación.

 

Por eso, cuando usas: "*p = *j", estás utilizando sólo el Heap. Cuando usas "strcpy", estás leyendo y escribiendo en el Stack.

 

Espero haberme explicado. Un saludo!!

El 22 de abril de 2012 17:43, Dani <dani <at> azthe.com> escribió:

¡Buenas a todos!

 

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

 

*p=*j;

memcpy(p, j  , sizeof(struct q));

 

Espero que alguien me pueda sacar de la duda.

Gracias.

 

_______________________________________________
CRySoL mailing list
http://crysol.org/
https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol



 

--
Miguel Ángel García Martínez

 

 



 

--
Miguel Ángel García Martínez

 

 


Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo.
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at
http://www.tid.es/ES/PAGINAS/disclaimer.aspx
<div>
<div class="WordSection1">
<p class="MsoNormal"><span>Buenas,<p></p></span></p>
<p class="MsoNormal"><span><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span>Cuando comentas lo del heap/stack, me surge la duda de si no es al rev&eacute;s (al menos as&iacute; lo ten&iacute;a yo interiorizado). Es decir, el stack es donde se almacenan
 las variables de una funci&oacute;n y al retornar de la funci&oacute;n se eliminan del stack y con operaciones malloc reservas memoria en el heap; que no es ni m&aacute;s ni menos que memoria paginada reservada por el SO para el proceso. Corresponde al proceso la liberaci&oacute;n de
 las p&aacute;ginas reservadas en el heap.<p></p></span></p>
<p class="MsoNormal"><span><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span>Saludos!<p></p></span></p>
<p class="MsoNormal"><span><p>&nbsp;</p></span></p>
<div>
<p class="MsoNormal"><span>De:</span><span> crysol-bounces <at> arco.esi.uclm.es [mailto:crysol-bounces <at> arco.esi.uclm.es]
En nombre de Dani<br>Enviado el: domingo, 22 de abril de 2012 23:31<br>Para: Miguel Angel<br>CC: Lista CRySoL<br>Asunto: Re: [CRySoL] Diferencia entre *p=*p y memcpy<p></p></span></p>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
<div>
<div>
<p class="MsoNormal">&iexcl;Muchas gracias por todo! Lo has explicado muy bien y de paso, ahora entiendo por qu&eacute; existen los ** XD&nbsp;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Probar&eacute; DDD, a ver que tal se me da.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Saludos.<p></p></p>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 21:37, Miguel Angel &lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt; escribi&oacute;:<p></p></p>
<p class="MsoNormal">Tienes que diferenciar entre la posici&oacute;n de memoria en la que se almacenan las variables y la direcci&oacute;n a la que apuntan. De esta manera, la posici&oacute;n de memoria en la que se encuentra "p" contiene, exactamente, la posici&oacute;n de memoria de
 "*p".<p></p></p>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Y deber&iacute;a aplicarme el cuento, ya que me equivoqu&eacute; :D<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Cuando usas "*p = *j" est&aacute;s diciendo: all&iacute; donde apunta p, guarda lo que apunta j". Pero como una imagen vale m&aacute;s que mil palabras, te mando la imagen (punteros.png).<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Te invito a que t&uacute; tambi&eacute;n utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 a&ntilde;os, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">El c&oacute;digo es el siguiente:<p></p></p>
</div>
<div>
<blockquote>
<div>
<div>
<p class="MsoNormal">int main()<p></p></p>
</div>
<div>
<p class="MsoNormal">{<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int value = 5;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* a;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* b;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* j;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* k;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; a = &amp;value;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; b = a;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; j = &amp;value;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; *k = *j;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; return 0;<p></p></p>
</div>
<div>
<p class="MsoNormal">}<p></p></p>
</div>
</div>
</blockquote>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Sin embargo, con este c&oacute;digo s&iacute; que ser&iacute;a v&aacute;lido:<p></p></p>
</div>
<div>
<blockquote>
<div>
<div>
<p class="MsoNormal">int main()<p></p></p>
</div>
<div>
<p class="MsoNormal">{<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int value = 5;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* a;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* b;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int** j;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; int** k;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; a = &amp;value;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; j = &amp;a;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; k = &amp;b;<p></p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; *k = *j;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">&nbsp; return 0;<p></p></p>
</div>
<div>
<p class="MsoNormal">}<p></p></p>
</div>
</div>
</blockquote>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
<div>
<p class="MsoNormal">Como ver&aacute;s, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">En fin... espero haberlo explicado bien (ahora s&iacute;) :D<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Un saludo!<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 20:39, Dani &lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt; escribi&oacute;:<p></p></p>
<div>
<div>
<blockquote>
<p class="MsoNormal"><p>&nbsp;</p></p>
<div>
<p class="MsoNormal">Gracias Miguel &Aacute;ngel por haberte tomado el tiempo de explic&aacute;rmelo.&nbsp;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Pero solo tengo una pregunta m&aacute;s, cuando dices:<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<div>
<p class="MsoNormal">Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria.<p></p></p>
</div>
<p class="MsoNormal">&iquest;Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, cre&iacute;a que cuando se hac&iacute;a la operaci&oacute;n *p=*j, imaginando que son enteros, &iquest;no se crea una nueva posici&oacute;n de memoria? Es decir, que si modifico j, no cambiar&iacute;a el valor de p;<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Saludos.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 19:10, Miguel Angel &lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt; escribi&oacute;:<p></p></p>
<div>
<div>
<blockquote>
<p class="MsoNormal"><p>&nbsp;</p></p>
<p class="MsoNormal">Hola!!<p></p></p>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Para entenderlo bien, lo suyo es que comprendas c&oacute;mo funciona un puntero.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">B&aacute;sicamente, cuando tienes un puntero que apunta a una estructura, est&aacute;s guardando datos en dos sitios: por una parte, el puntero es una direcci&oacute;n de memoria, que se guardar&aacute; en el Heap; por otro, la estructura estar&aacute; almacenada en la posici&oacute;n
 de memoria, en el Stack.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrar&aacute;n en el Heap, y la propia estructura,
 que estar&aacute; en el Stack.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Cuando utilizas memcpy, lo que est&aacute;s haciendo es realizar una copia de la posici&oacute;n de memoria (el Stack) en otro sitio(tambi&eacute;n en el Stack). Ten cuidado, porque memcpy no reservar&aacute; esa memoria.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Si comprendes la diferencia entre el Heap y el Stack, todo es m&aacute;s sencillo. Cuando haces:<p></p></p>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
int i;<p></p>
</li>
<li class="MsoNormal">
void* pointer;<p></p>
</li>
</ul>
<div>
<p class="MsoNormal">etc, est&aacute;s reservando memoria en el Heap. &Eacute;sta es vol&aacute;til y la suele gestionar el propio compilador.<p></p></p>
</div>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) est&aacute;s usando el Stack, y eres t&uacute; el encargado de gestionar su liberaci&oacute;n.<p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Por eso, cuando usas: "*p = *j", est&aacute;s utilizando s&oacute;lo el Heap. Cuando usas "strcpy", est&aacute;s leyendo y escribiendo en el Stack.<p></p></p>
</div>
<div>
<p class="MsoNormal"><br>
Pint&aacute;ndolo:&nbsp;<a href="http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C" target="_blank">http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C</a><p></p></p>
</div>
<div>
<p class="MsoNormal">Diferencias entre el Heap y el Stack:&nbsp;<a href="http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory" target="_blank">http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory</a><p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal">Espero haberme explicado. Un saludo!!<p></p></p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 17:43, Dani &lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt; escribi&oacute;:<p></p></p>
<div>
<div>
<p class="MsoNormal"><span>&iexcl;Buenas a todos!</span><p></p></p>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal"><span>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</span><p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal"><span>*p=*j;</span><p></p></p>
</div>
<div>
<p class="MsoNormal"><span>memcpy(p,&nbsp;j &nbsp;, sizeof(struct q));</span><p></p></p>
</div>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<div>
<p class="MsoNormal"><span>Espero que alguien me pueda sacar de la duda.</span><p></p></p>
</div>
<div>
<p class="MsoNormal"><span>Gracias.</span><p></p></p>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
CRySoL mailing list<br><a href="http://crysol.org/" target="_blank">http://crysol.org/</a><br><a href="https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol" target="_blank">https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol</a><p></p></p>
</div>
<p class="MsoNormal"><span><br><br clear="all"><p></p></span></p>
<div>
<p class="MsoNormal"><span><p>&nbsp;</p></span></p>
</div>
<p class="MsoNormal"><span>-- <br>
Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<p></p></span></p>
<div>
<p class="MsoNormal"><span><a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><p></p></span></p>
<p class="MsoNormal"><span><a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a>
 |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <p></p></span></p>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
</blockquote>
</div>
</div>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
</blockquote>
</div>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><br><br clear="all"><p></p></p>
<div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
<p class="MsoNormal">-- <br>
Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<p></p></p>
<div>
<p class="MsoNormal"><a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><p></p></p>
<p class="MsoNormal"><a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a>
<p></p></p>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div>
</div>
<br>Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra pol&iacute;tica de env&iacute;o y recepci&oacute;n de correo electr&oacute;nico en el enlace situado m&aacute;s abajo.<br>
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at<br>
http://www.tid.es/ES/PAGINAS/disclaimer.aspx<br>
</div>
Miguel Angel | 23 Apr 2012 06:59
Picon
Gravatar

Re: Diferencia entre *p=*p y memcpy

Correcto: el heap es donde se reserva memoria (*alloc) y el stack donde se guardan las variables.

Perdón por la confusión.

El 23 de abril de 2012 00:08, JAVIER CHICO CESPEDES <jcc <at> tid.es> escribió:

Buenas,

 

Cuando comentas lo del heap/stack, me surge la duda de si no es al revés (al menos así lo tenía yo interiorizado). Es decir, el stack es donde se almacenan las variables de una función y al retornar de la función se eliminan del stack y con operaciones malloc reservas memoria en el heap; que no es ni más ni menos que memoria paginada reservada por el SO para el proceso. Corresponde al proceso la liberación de las páginas reservadas en el heap.

 

Saludos!

 

De: crysol-bounces <at> arco.esi.uclm.es [mailto:crysol-bounces <at> arco.esi.uclm.es] En nombre de Dani
Enviado el: domingo, 22 de abril de 2012 23:31
Para: Miguel Angel
CC: Lista CRySoL
Asunto: Re: [CRySoL] Diferencia entre *p=*p y memcpy

 

¡Muchas gracias por todo! Lo has explicado muy bien y de paso, ahora entiendo por qué existen los ** XD 

 

Probaré DDD, a ver que tal se me da.

 

Saludos.

 

El 22 de abril de 2012 21:37, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:

Tienes que diferenciar entre la posición de memoria en la que se almacenan las variables y la dirección a la que apuntan. De esta manera, la posición de memoria en la que se encuentra "p" contiene, exactamente, la posición de memoria de "*p".

 

Y debería aplicarme el cuento, ya que me equivoqué :D

 

Cuando usas "*p = *j" estás diciendo: allí donde apunta p, guarda lo que apunta j". Pero como una imagen vale más que mil palabras, te mando la imagen (punteros.png).

 

Te invito a que tú también utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 años, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).

 

Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D

 

El código es el siguiente:

int main()

{

  int value = 5;

 

  int* a;

  int* b;

 

  int* j;

  int* k;

 

  a = &value;

  b = a;

 

  j = &value;

  *k = *j;

 

 

  return 0;

}

 

Sin embargo, con este código sí que sería válido:

int main()

{

  int value = 5;

 

  int* a;

  int* b;

 

  int** j;

  int** k;

 

  a = &value;

 

  j = &a;

  k = &b;

  *k = *j;

 

  return 0;

}

 

Como verás, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).

 

En fin... espero haberlo explicado bien (ahora sí) :D

 

Un saludo!

 

El 22 de abril de 2012 20:39, Dani <dani <at> azthe.com> escribió:

 

Gracias Miguel Ángel por haberte tomado el tiempo de explicármelo. 

 

Pero solo tengo una pregunta más, cuando dices:

 

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria.

¿Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, creía que cuando se hacía la operación *p=*j, imaginando que son enteros, ¿no se crea una nueva posición de memoria? Es decir, que si modifico j, no cambiaría el valor de p;

 

Saludos.

 

El 22 de abril de 2012 19:10, Miguel Angel <miguelangel.garcia <at> gmail.com> escribió:

 

Hola!!

 

Para entenderlo bien, lo suyo es que comprendas cómo funciona un puntero.

 

Básicamente, cuando tienes un puntero que apunta a una estructura, estás guardando datos en dos sitios: por una parte, el puntero es una dirección de memoria, que se guardará en el Heap; por otro, la estructura estará almacenada en la posición de memoria, en el Stack.

 

Cuando igualas punteros, sólo estás haciendo que ambas variables apunten a la misma posición de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrarán en el Heap, y la propia estructura, que estará en el Stack.

 

Cuando utilizas memcpy, lo que estás haciendo es realizar una copia de la posición de memoria (el Stack) en otro sitio(también en el Stack). Ten cuidado, porque memcpy no reservará esa memoria.

 

Si comprendes la diferencia entre el Heap y el Stack, todo es más sencillo. Cuando haces:

  • int i;
  • void* pointer;

etc, estás reservando memoria en el Heap. Ésta es volátil y la suele gestionar el propio compilador.

 

Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) estás usando el Stack, y eres tú el encargado de gestionar su liberación.

 

Por eso, cuando usas: "*p = *j", estás utilizando sólo el Heap. Cuando usas "strcpy", estás leyendo y escribiendo en el Stack.

 

Espero haberme explicado. Un saludo!!

El 22 de abril de 2012 17:43, Dani <dani <at> azthe.com> escribió:

¡Buenas a todos!

 

Pues simplemente quería preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:

 

*p=*j;

memcpy(p, j  , sizeof(struct q));

 

Espero que alguien me pueda sacar de la duda.

Gracias.

 

_______________________________________________
CRySoL mailing list
http://crysol.org/
https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol



 

--
Miguel Ángel García Martínez

 

 



 

--
Miguel Ángel García Martínez

 

 


Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo.
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at
http://www.tid.es/ES/PAGINAS/disclaimer.aspx



--
Miguel Ángel García Martínez
<div>
<div>Correcto: el heap es donde se reserva memoria (*alloc) y el stack donde se guardan las variables.</div>
<div><br></div>
<div>Perd&oacute;n por la confusi&oacute;n.<br><br><div class="gmail_quote">El 23 de abril de 2012 00:08, JAVIER CHICO CESPEDES <span dir="ltr">&lt;<a href="mailto:jcc <at> tid.es">jcc <at> tid.es</a>&gt;</span> escribi&oacute;:<br><blockquote class="gmail_quote">

<div lang="ES" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span>Buenas,</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Cuando comentas lo del heap/stack, me surge la duda de si no es al rev&eacute;s (al menos as&iacute; lo ten&iacute;a yo interiorizado). Es decir, el stack es donde se almacenan
 las variables de una funci&oacute;n y al retornar de la funci&oacute;n se eliminan del stack y con operaciones malloc reservas memoria en el heap; que no es ni m&aacute;s ni menos que memoria paginada reservada por el SO para el proceso. Corresponde al proceso la liberaci&oacute;n de
 las p&aacute;ginas reservadas en el heap.</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Saludos!</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<div>
<p class="MsoNormal"><span>De:</span><span> <a href="mailto:crysol-bounces <at> arco.esi.uclm.es" target="_blank">crysol-bounces <at> arco.esi.uclm.es</a> [mailto:<a href="mailto:crysol-bounces <at> arco.esi.uclm.es" target="_blank">crysol-bounces <at> arco.esi.uclm.es</a>]
En nombre de Dani<br>Enviado el: domingo, 22 de abril de 2012 23:31<br>Para: Miguel Angel<br>CC: Lista CRySoL<br>Asunto: Re: [CRySoL] Diferencia entre *p=*p y memcpy</span></p>
</div>
<div><div class="h5">
<p class="MsoNormal">&nbsp;</p>
<div>
<div>
<p class="MsoNormal">&iexcl;Muchas gracias por todo! Lo has explicado muy bien y de paso, ahora entiendo por qu&eacute; existen los ** XD&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Probar&eacute; DDD, a ver que tal se me da.</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Saludos.</p>
</div>
<p class="MsoNormal">&nbsp;</p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 21:37, Miguel Angel &lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt; escribi&oacute;:</p>
<p class="MsoNormal">Tienes que diferenciar entre la posici&oacute;n de memoria en la que se almacenan las variables y la direcci&oacute;n a la que apuntan. De esta manera, la posici&oacute;n de memoria en la que se encuentra "p" contiene, exactamente, la posici&oacute;n de memoria de
 "*p".</p>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Y deber&iacute;a aplicarme el cuento, ya que me equivoqu&eacute; :D</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Cuando usas "*p = *j" est&aacute;s diciendo: all&iacute; donde apunta p, guarda lo que apunta j". Pero como una imagen vale m&aacute;s que mil palabras, te mando la imagen (punteros.png).</p>

</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Te invito a que t&uacute; tambi&eacute;n utilices DDD. Es un poco raro al principio, ya que no se ha actualizado en casi 10 a&ntilde;os, pero puedo asegurarte que no he visto un depurador mejor (ni .Net, Java ni leches).</p>

</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Como ves, cuando hago el "*k = *j" tengo un segmentation fault, ya que estoy haciendo una burrada :D</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">El c&oacute;digo es el siguiente:</p>
</div>
<div>
<blockquote>
<div>
<div>
<p class="MsoNormal">int main()</p>
</div>
<div>
<p class="MsoNormal">{</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int value = 5;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* a;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* b;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* j;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* k;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; a = &amp;value;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; b = a;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; j = &amp;value;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; *k = *j;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; return 0;</p>
</div>
<div>
<p class="MsoNormal">}</p>
</div>
</div>
</blockquote>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Sin embargo, con este c&oacute;digo s&iacute; que ser&iacute;a v&aacute;lido:</p>
</div>
<div>
<blockquote>
<div>
<div>
<p class="MsoNormal">int main()</p>
</div>
<div>
<p class="MsoNormal">{</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int value = 5;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* a;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int* b;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int** j;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; int** k;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; a = &amp;value;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; j = &amp;a;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; k = &amp;b;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; *k = *j;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp; return 0;</p>
</div>
<div>
<p class="MsoNormal">}</p>
</div>
</div>
</blockquote>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
<div>
<p class="MsoNormal">Como ver&aacute;s, puedo hacer "*k = *j" porque ambos son punteros a punteros (punteros2.png).</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">En fin... espero haberlo explicado bien (ahora s&iacute;) :D</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Un saludo!</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 20:39, Dani &lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt; escribi&oacute;:</p>
<div>
<div>
<blockquote>
<p class="MsoNormal">&nbsp;</p>
<div>
<p class="MsoNormal">Gracias Miguel &Aacute;ngel por haberte tomado el tiempo de explic&aacute;rmelo.&nbsp;</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Pero solo tengo una pregunta m&aacute;s, cuando dices:</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<div>
<p class="MsoNormal">Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria.</p>
</div>
<p class="MsoNormal">&iquest;Eso no ocurre si, por ejemplo, hago p=j;? Hasta ahora, cre&iacute;a que cuando se hac&iacute;a la operaci&oacute;n *p=*j, imaginando que son enteros, &iquest;no se crea una nueva posici&oacute;n de memoria? Es decir, que si modifico j, no cambiar&iacute;a el valor de p;</p>

</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Saludos.</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 19:10, Miguel Angel &lt;<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">miguelangel.garcia <at> gmail.com</a>&gt; escribi&oacute;:</p>
<div>
<div>
<blockquote>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Hola!!</p>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Para entenderlo bien, lo suyo es que comprendas c&oacute;mo funciona un puntero.</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">B&aacute;sicamente, cuando tienes un puntero que apunta a una estructura, est&aacute;s guardando datos en dos sitios: por una parte, el puntero es una direcci&oacute;n de memoria, que se guardar&aacute; en el Heap; por otro, la estructura estar&aacute; almacenada en la posici&oacute;n
 de memoria, en el Stack.</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Cuando igualas punteros, s&oacute;lo est&aacute;s haciendo que ambas variables apunten a la misma posici&oacute;n de memoria. En este caso tenemos tres zonas de memoria: el puntero inicial y el segundo, que se encontrar&aacute;n en el Heap, y la propia estructura,
 que estar&aacute; en el Stack.</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Cuando utilizas memcpy, lo que est&aacute;s haciendo es realizar una copia de la posici&oacute;n de memoria (el Stack) en otro sitio(tambi&eacute;n en el Stack). Ten cuidado, porque memcpy no reservar&aacute; esa memoria.</p>

</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Si comprendes la diferencia entre el Heap y el Stack, todo es m&aacute;s sencillo. Cuando haces:</p>
</div>
<div>
<ul type="disc">
<li class="MsoNormal">
int i;</li>
<li class="MsoNormal">
void* pointer;</li>
</ul>
<div>
<p class="MsoNormal">etc, est&aacute;s reservando memoria en el Heap. &Eacute;sta es vol&aacute;til y la suele gestionar el propio compilador.</p>
</div>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Cuando utilizas las funciones *alloc (Malloc, Alloc, Calloc, Strdup, ...) est&aacute;s usando el Stack, y eres t&uacute; el encargado de gestionar su liberaci&oacute;n.</p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Por eso, cuando usas: "*p = *j", est&aacute;s utilizando s&oacute;lo el Heap. Cuando usas "strcpy", est&aacute;s leyendo y escribiendo en el Stack.</p>
</div>
<div>
<p class="MsoNormal"><br>
Pint&aacute;ndolo:&nbsp;<a href="http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C" target="_blank">http://video.google.com/videoplay?docid=-3462836456663764635&amp;q=Pointer+C</a></p>
</div>
<div>
<p class="MsoNormal">Diferencias entre el Heap y el Stack:&nbsp;<a href="http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory" target="_blank">http://wiki.answers.com/Q/What_is_difference_between_heap_memory_and_stack_memory</a></p>

</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal">Espero haberme explicado. Un saludo!!</p>
<div>
<p class="MsoNormal">El 22 de abril de 2012 17:43, Dani &lt;<a href="mailto:dani <at> azthe.com" target="_blank">dani <at> azthe.com</a>&gt; escribi&oacute;:</p>
<div>
<div>
<p class="MsoNormal"><span>&iexcl;Buenas a todos!</span></p>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal"><span>Pues simplemente quer&iacute;a preguntaros cual es la diferencia entre las siguientes sentencias, siendo variables definidas por una estructura g, en C:</span></p>

</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal"><span>*p=*j;</span></p>
</div>
<div>
<p class="MsoNormal"><span>memcpy(p,&nbsp;j &nbsp;, sizeof(struct q));</span></p>
</div>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<div>
<p class="MsoNormal"><span>Espero que alguien me pueda sacar de la duda.</span></p>
</div>
<div>
<p class="MsoNormal"><span>Gracias.</span></p>
</div>
<p class="MsoNormal">&nbsp;</p>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
CRySoL mailing list<br><a href="http://crysol.org/" target="_blank">http://crysol.org/</a><br><a href="https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol" target="_blank">https://arco.esi.uclm.es/cgi-bin/mailman/listinfo/crysol</a></p>
</div>
<p class="MsoNormal"><span><br><br clear="all"></span></p>
<div>
<p class="MsoNormal"><span>&nbsp;</span></p>
</div>
<p class="MsoNormal"><span>-- <br>
Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez</span></p>
<div>
<p class="MsoNormal"><span><a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a></span></p>
<p class="MsoNormal"><span><a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a>
 |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> 
</span></p>
</div>
<p class="MsoNormal">&nbsp;</p>
</div>
</blockquote>
</div>
</div>
</div>
<p class="MsoNormal">&nbsp;</p>
</div>
</blockquote>
</div>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><br><br clear="all"></p>
<div>
<p class="MsoNormal">&nbsp;</p>
</div>
<p class="MsoNormal">-- <br>
Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez</p>
<div>
<p class="MsoNormal"><a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a></p>
<p class="MsoNormal"><a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a>
</p>
</div>
<p class="MsoNormal">&nbsp;</p>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal">&nbsp;</p>
</div>
</div></div>
</div>
<br>Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra pol&iacute;tica de env&iacute;o y recepci&oacute;n de correo electr&oacute;nico en el enlace situado m&aacute;s abajo.<br>
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at<br><a href="http://www.tid.es/ES/PAGINAS/disclaimer.aspx" target="_blank">http://www.tid.es/ES/PAGINAS/disclaimer.aspx</a><br>
</div>

</blockquote>
</div>
<br><br clear="all"><div><br></div>-- <br>Miguel &Aacute;ngel Garc&iacute;a Mart&iacute;nez<div>
<a href="http://www.magmax.org" target="_blank">http://www.magmax.org</a><br><div>
<a href="mailto:miguelangel.garcia <at> gmail.com" target="_blank">Mail</a>&nbsp;|&nbsp;<a href="http://twitter.com/#magmax9" target="_blank">Twitter</a>&nbsp;|&nbsp;<a href="http://www.linkedin.com/in/miguelangelgarciamartinez" target="_blank">LinkedIn</a> |&nbsp;<a href="http://about.me/miguelangelgarcia" target="_blank">about.me</a> <br>
</div>
</div>
<br>
</div>
</div>
Ricardo Ruedas | 23 Apr 2012 22:35
Picon
Gravatar

Re: Diferencia entre *p=*p y memcpy

Ambas sentencias son equivalentes en comportamiento para el caso que
comentas. Yo usaría la primera por ser más corta y más legible.

Saludos

Gmane