Objetos dinámicos

El uso principal y más potente de los punteros es el manejo de la memoria dinámica.

La memoria se clasifica en muchas categorías, por ahora nos centraremos en algunas de ellas. Cuando se ejecuta un programa, el sistema operativo reserva una zona de memoria para el código o instrucciones del programa y otra para los objetos que se usan durante la ejecución. A menudo estas zonas son la misma, y componen lo que se denomina memoria local. También hay otras zonas de memoria, como la pila, que se usa, entre otras cosas, para intercambiar datos entre las funciones. El resto, la memoria que no se usa por ningún programa es lo que se conoce como heap o montón. Nuestro programa puede hacer uso de esa memoria durante la ejecución, de modo que la cantidad de espacio de memoria usado por el programa no está limitada por el diseño ni por las declaraciones de objetos realizadas en el código fuente. Por eso se denomina a este tipo, memoria dinámica, ya que tanto la cantidad de memoria como su uso se deciden durante la ejecución, y en general, cambia a lo largo del tiempo, de forma dinámica. Para ello, normalmente se usará memoria del montón, y no se llama así porque sea de peor calidad, sino porque suele haber un buen montón de memoria de este tipo.

C++ dispone de dos operadores para manejar (reservar y liberar) la memoria dinámica, son new y delete. En C estas acciones se realizan mediante funciones de la biblioteca estándar stdio.

Hay una regla de oro cuando se usa memoria dinámica: toda la memoria que se reserve durante el programa hay que liberarla antes de salir del programa. No seguir esta regla es una actitud muy irresponsable, y en la mayor parte de los casos tiene consecuencias desastrosas. No os fiéis de lo que diga el compilador, de que estas variables se liberan solas al terminar el programa, no siempre es verdad.

Veremos con mayor profundidad los operadores new y delete en el siguiente capítulo, por ahora veremos un ejemplo:

#include <iostream>
using namespace std;
 
int main() { 
   int *a; 
   char *b; 
   float *c; 
   struct stPunto { 
      float x,y; 
   } *d;
 
   a = new int; 
   b = new char; 
   c = new float; 
   d = new stPunto;
 
   *a = 10; 
   *b = 'a'; 
   *c = 10.32; 
   d->x = 12; d->y = 15;
 
   cout << "a = " << *a << endl; 
   cout << "b = " << *b << endl; 
   cout << "c = " << *c << endl; 
   cout << "d = (" << d-&gt;x << ", " 
        << d->y << ")" << endl;
 
   delete a; 
   delete b; 
   delete c; 
   delete d; 

   return 0; 
}

Y mucho cuidado: si pierdes un puntero a una variable reservada dinámicamente, no podrás liberarla.

Ejemplo:

int main()
{
   int *a;
 
   a = new int; // variable dinámica
   *a = 10;
   a = new int; // nueva variable dinámica, 
                // se pierde el puntero a la anterior
   *a = 20;
   delete a;  // sólo liberamos la última reservada
   return 0;
}

En este ejemplo vemos cómo es imposible liberar la primera reserva de memoria dinámica. Lo correcto, si no la necesitábamos habría sido liberarla antes de reservar un nuevo bloque usando el mismo puntero, y si la necesitamos, habría que guardar su dirección, por ejemplo usando otro puntero.

Problemas

  1. Escribir un programa con una función que calcule la longitud de una cadena de caracteres. El nombre de la función será LongitudCadena, debe devolver un int, y como parámetro de entrada debe tener un puntero a char.
    En esta función no se pueden usar enteros para recorrer el array, usar sólo punteros y aplicar aritmética de punteros.
    En main probar con distintos tipos de cadenas: arrays y punteros.
  2. Escribir un programa con una función que busque un carácter determinado en una cadena. El nombre de la función será BuscaCaracter, debe devolver un int con la posición en que fue encontrado el carácter, si no se encontró volverá con -1. Los parámetros de entrada serán una cadena y un carácter. En la función main probar con distintas cadenas y caracteres.
  3. Implementar en una función el siguiente algoritmo para ordenar un array de enteros.
    La idea es recorrer simultáneamente el array desde el principio y desde el final, comparando los elementos. Si los valores comparados no están en el orden adecuado, se intercambian y se vuelve a empezar el bucle. Si están bien ordenados, se compara el siguiente par.
    El proceso termina cuando los punteros se cruzan, ya que eso indica que hemos comparado la primera mitad con la segunda y todos los elementos estaban en el orden correcto.
    Usar una función con tres parámetros:
    void Ordenar(int* vector, int nElementos, bool ascendente);
    De nuevo, no se deben usar enteros, sólo punteros y aritmética de punteros.

Comentarios de los usuarios (25)

Alejandro Alcalde
2010-09-15 21:46:51

Hola, dejo aqui el ejercicio 1, por si a alguien le sirve, y ya de paso, me digan si es correcto. Pero o entendi a que se refirio con \'En main probar con distintos tipos de cadenas: arrays y punteros.\'

#include <iostream> 

using std::cout;
using std::cin;
using std::endl;

int lenCad(char*);

int main(int argc, char **argv)
{
	char cad[] = {\"Hola que tal\"}, *punteroC=cad;
	
	int resul = lenCad(cad);
	cout << \"La cadena tiene \" << resul  << \" caracteres\" << endl;
	
	return 0;
}
//-------------------------------
int lenCad(char* cad){
	char* copia = cad;
	
	int i=0;
	while(*copia++) i++;

	return i;
}

Una ultima duda, me lio mucho con los punteros, y nose porque, si en el while pongo copia++ en vez de *copia++ entra en un bucle infinito.

Creo que es porque con *copia++ estoy diciendo \'avanza uno en el contenido de copia, osea copia[1]\', y con copia++, no avanzaria sizeof(char)??, osea, el siguente elemento del array?? :), siento rebuscar tanto la pregunta, pero es que estuve un tiempo sin ensayar con punteros, y ahora me cuesta volver a entenderlos.

Salusod

b0ch0n
2010-10-05 21:17:09

Alejandro creo que conviene usar el puntero como está explicado en el principio del capitulo

*;

y no como

* ;

para tratar la variable como si el asterisco formara parte del nombre de la variable, igualmente con el ampersand(&), entonces con * manipulas lo apuntado, mientras que con & manipulas el contenido de lo apuntado

Nota del administrador: Hemos eliminado el código ya que las soluciones a los problemas no se han incluido de forma intencionada. La idea es que cada uno haga sus propios problemas a su modo.

b0ch0n
2010-10-06 20:10:24

Me equivoque una vez más!

Comentario anterior:

entonces con * manipulas lo apuntado, mientras que con & manipulas el contenido de lo apuntado

Debe ser:

entonces con * manipulas el contenido apuntado, mientras que con & manipulas la direccion apuntada

3rr4r 3s hum4n0

b0ch0n
2010-10-13 02:20:55

Ejercicio 2

Espero que comenten si alguna forma de asignar los valores no sea la adecuada

Nota del administrador: Hemos eliminado el código ya que las soluciones a los problemas no se han incluido de forma intencionada. La idea es que cada uno haga sus propios problemas a su modo.

b0ch0n
2010-10-15 02:35:48

Ejercicio 3

http://codepad.org/GN3Stea6

Nota del administrador: Hemos eliminado el código ya que las soluciones a los problemas no se han incluido de forma intencionada. La idea es que cada uno haga sus propios problemas a su modo.

Randolph Carter
2010-12-16 06:46:10

Problema 12.1

// Problema 12.1

#include <iostream>
using namespace std;

int LongitudCadena(char*);

int main()
{
    char cadena[] = \"Camaleon\";
    char *pcadena = cadena;
        
    cout << \"La cadena \'\" << cadena << \"\' tiene \" 
    << LongitudCadena(pcadena) << \" caracteres.\" << endl;
}

int LongitudCadena(char* puntero)
{
    char* copia = puntero;
    while(*puntero) puntero++;
    return(puntero-copia);
}

Como la idea del problema, supongo yo, era usar al máximo las cualidades de los punteros preferí, para calcular la longitud de la cadena, usar dos punteros: uno llamado \'copia\' dejarlo en el punto inicial del array y el otro, llamado \'puntero\' (que original), hacerlo avanzar por la cadena hasta encontrar el fin de esta (el caracter \'0\').

No sé si esta es la forma más eficiente de hacerlo, pero me pareció la más pertinente por lo menos.

Jorge
2011-01-19 12:48:30

//

// EJERCICIO 2

//

#include <iostream>

using namespace std;

int buscarCaracter( char *pC, char c);

int main() {

char cad[10];

cout << "Introduzca cadena" << endl;

cin >> cad;

cin.get();

if (buscarCaracter(cad, 'o') == -1) cout << "No encontrado" << endl;

else cout << buscarCaracter( cad, 'o') << endl;

// Busca la o en una cadena introducida directamente

// la cual ya se que que tiene una o por eso no evaluo

cout << "La o en Paco se encuentra en la posicion " << buscarCaracter("Paco", 'o');

cin.get();

return 0;

}

int buscarCaracter( char *pC, char c){

//Funcion que busca un caracter pasado con argumento

// IN: puntero tipo caracter, y un caracter

// OUT: entero como numero de chars recorridos por el puntero

// o -1 si no encontrado

bool encontrado;

char *copia;

copia = pC;

encontrado = false;

while ((*pC++)&&(!encontrado))

if (*pC == c) encontrado = true;

if (encontrado) return ((pC-copia)/sizeof(char));

else return -1;

}

carlos
2011-04-17 16:40:09

hola ojala me puedan ayudar. pasa que estoy haciendo un proyecto para una clase de programacion en c++ y este es mi primer bosquejo. Lo que pasa es que es que los dos arreglos al agregarle datos al primero me le agrega los que le doy para el segundo. y es creo por hacer *A=NULL y *B=NULL.

pero si se los quto me hace errores. me podrian ayudar por favor... gracias

#include<iostream.h>

void crea(float *,int );
void ingresa(float *,int );
void visualiza(float *,int );
int busca(float *, float,int );
int cardinalidad(float *,int );
void agrega(float *,int *);
void quita(float *,int *);

void main(void){
float *A0=NULL,*B=NULL,eb;
int N,N1;
char res;
cout<<"\nDE CUANTOS ELEMENTOS QUIERE EL CONJUNTO A: ";
cin>>N;
crea(A,N);
ingresa(A,N);
cout<<"\nDE CUANTOS ELEMENTOS QUIERE EL CONJUNTO B: ";
cin>>N1;
crea(B,N1);
ingresa(B,N1);
cout<<"\nEL CONJUNTO A TIENE ESTOS ELEMENTOS: ";
visualiza(A,N);
cout<<"\nEL CONJUNTO B TIENE ESTOS ELEMENTOS: ";
visualiza(B,N1);

cout<<"\n\nEN CUAL CONJUNTO DESEA BUSCAR EL ELEMENTO EN EL A O EL B: ";
cin>>res;
if (res=='A') {
cout<<"\n\nINTRODUSCA EL ELEMENTO A BUSCAR EN A: ";
cin>>eb;
cout<<"\nEl elemento: "<<eb<<" Fue encontrado "<<busca(A,eb,N)<<" veces";
 }
else
{cout<<"\n\nINTRODUSCA EL ELEMENTO A BUSCAR EN B: ";
cin>>eb;
cout<<"\nEl elemento: "<<eb<<" Fue encontrado "<<busca(B,eb,N1)<<" veces";
}

cout<<"\nLA CARDINALIDAD ES DE: "<<cardinalidad(A,N)<<" ELEMENTOS EN EL CONJUNTO A";
cout<<"\nLA CARDINALIDAD ES DE: "<<cardinalidad(B,N1)<<" ELEMENTOS EN EL CONJUNTO B";
cout<<"\n\nEN CUAL CONJUNTO DESEA AGREGAR UN ELEMENTO EN EL A O EL B: ";
cin>>res;
 if (res=='A') {
agrega(A,&N);
visualiza(A,N);
quita(A,&N);
visualiza(A,N);}
else{
agrega(B,&N1);
visualiza(B,N1);
quita(B,&N1);
visualiza(B,N1);}
delete []A;
delete []B;
cin.get();
cin.get();
}

void crea(float *x,int n){
x=new float[n];
}

void ingresa(float *x,int n){
int i;
float ing;
for(i=0;i<n;i++){
cout<<"\nElemento "<<i+1<<": ";
cin>>ing;
x[i]=ing;}}

void visualiza(float *x,int n){
int i;
cout<<"\nA= {";
for(i=0;i<n;i++){
cout<<x[i];
if(i!=n-1)
cout<<", ";}
cout<<"}";}

int busca(float *x,float elem,int n){
int i, cont=0;
for(i=0;i<n;i++){
if(x[i]==elem)
cont++;}
return cont;}

int cardinalidad(float *x,int n){
int i, cont=0;
for(i=0;i<n;i++)
cont++;
return cont;}

void agrega(float *x, int *n){
int i;
float *q=NULL,ei;
q=new float[*n];
q=x;
delete []x;
x=new float[*n+1];
x=NULL;
x=q;
cout<<"\nElemento a agregar: ";
cin>>ei;
x[*n]=ei;
delete []q;
*n=*n+1;
}

void quita(float *x,int *n){
int i,en,j=0;
float *q=NULL,eq;
q=new float[*n];
q=x;
cout<<"\nElemento a quitar: ";
cin>>eq;
en=busca(x,eq,*n);
if(en==NULL)
cout<<"\nEl elemento que desea quitar no existe";
else{
delete []x;
x=new float[*n-en-1];
x=NULL;
for(i=0;i<*n;i++)
if(q[i]!=eq){
x[j]=q[i];
j=j+1;}
delete []q;
*n=*n-en;}
}
Steven
2011-04-17 20:19:31

Hola Carlos,

El problema que estás teniendo es que pasas los punteros, 'A' y 'B', a cada invocación de 'crear()' por copia (o por valor). Como 'crea()' sirve para modificar el valor del puntero que se le pasa, necesitas pasarlo por referencia. Como aún no hemos visto el paso por referencia, hasta que llegues al capítulo 15, podemos pasar la dirección de memoria del puntero como parámetro. Esto significa que 'crea()' requiere un doble puntero. Esto es,

void crea( float **x, int n );
...
void crea( float **x, int n )
{
  *x = new float[n];
}

Tendrás que pasar la dirección de memoria de los punteros a 'crea()'. Esto es,

crea( &A, N );
...
crea( &B, N );

Además, tienes un código algo raro en 'agrega()' y en 'quita()'. Creas memoria asignándola a un puntero, e inmediatamente modificas ese puntero para apuntar a otro lugar. Deberías revisar la lógica de estas implementaciones.

Aparte de este problema principal, quiero comentar que tu programa está escrito para un compilador antiguo. El estándar de C++ exige que escribas:

#include <iostream>

Y tendrías que usar el espacio con nombre 'std'. Además, 'main()' debe retornar 'int'; esto es,

int main()
{
  ...
  return 0;  // 0 => terminado con éxito
}

Por último, un puntero nulo es 0 (cero).

No he mirado todo el código, así que revísalo bien.

Espero que esto te ayude.

Steven

carlos
2011-04-18 04:19:49

si mi codigo es raro pues como digo es un bosquejo aun pues estoy haciendo que funcionen las operaciones que implementare, y despues lo tengo que hacer orientado a objetos usando claases. muchas gracias voi a checar si soluciono el problema con la ayuda que has dado y le aviso como va gracias

carlos
2011-04-18 04:37:04

hola pues el problema se soluciona pero hace lo mismo que si no les pusiera NULL. pues al agregar un dato y despues al visualizarlo el arreglo, el primer elemento me lo muestra como basura. espero me puedan ayudar pues me gusta mucho la programacion. Y pues veo que aun no an yegado a clases aqui, ojala me puedan asesorar por correo muchas gracias.

jesus
2011-06-22 03:36:33

quisiera que me ayuden con estos problemas

Se pide elaborar un programa que use punteros, el programa deberá calcular la suma de dos matrices cuadradas en una funcion.

1. Diseñar un programa que permita ingresar matrices utilizando punteros y que se realice la suma de estos.

2. Generar un programa que permita invertir el orden de una cadena ingresada por teclado, use punteros

3. Se pide generar un programa con una sola función invocada por referencia, la que se encargara de calcular el área de un circulo o un rectángulo o un trapecio, la función debe reconocer el tipo de cálculo a realizar, se debe devolver dos resultados, area y tipo de figura. (Utilizar solo punteros)

Diego
2011-06-24 07:45:33

He leido los primeros 12 capítulos de su página web y son increiblemente excepcionales, entendí muchas cosas que no las había entendido en clases, pero sobre todo llene los vacíos que tenía, ya que este curso es muy completo y muestra todos los sinónimos de una expresión, cosa que no lo suelen hacer todos. También me he reido bastante con algunas explicaciones que dan de las cosas inusuales, como las estructuras anónimas o las variables enmascaradas, que explica como acceder a ellas y luego dice la pregunta verdadera es que utilidad tiene esto, o los punteros laser que crean árboles. Pero aunque ese tipo de expresiones no se suela usar, es bueno saberlo, eso hace que sea un curso muy completo y de alta calidad, y por eso, estoy muy agradecido con ustedes por toda esa información que brindan, Gracias nada más que decir.

PD: Haciendo el problema uno creo que este es el codigo más conciso que cumple con las condiciones.

#include <iostream>
using namespace std;

int LongitudCadena(const char *Cadena);

int main(void)
{
     char *cadena = "Hola";
     char string[] = "Mundo";
     cout << "Longitud de " << cadena << " = " << LongitudCadena(cadena) << endl;
     cout << "Longitud de " << string << " = " << LongitudCadena(string) << endl;
     cin.get();
     return 0;
}

int LongitudCadena(const char *Cadena)
{
    int longitud=0;
    for(;*Cadena!=0; longitud++, Cadena++);
    return longitud;
}

Me gusta escribir con formalidad los programas, y ocupar la mayor cantidad de recursos posibles, con tal de disminuir el código y tratar de hacerlo más legible.

Carlitos
2011-10-22 20:44:19

No comprendo bien el algoritmo que se pretende en el ejercicio 3. Yo lo que malentiendo es esto (disculpeseme la abstrusa notación):

{ 4, 3, 7, 8 }

{ ptrH-->4, 3, 7, 8<--ptrL } //*ptrH > *ptrL ( No intercambio )

{ 4, ptrH-->3, 7<--ptrL, 8 } //*ptrH > *ptrL ( No intercambio )

{ 4, 3<--ptrL, ptrH-->7, 8 } // ptrH < ptrL (FIN)

{ 4, 3, 7, 8 } //Oh!

El algoritmo solo asegura que los valores de la primera mitad son menores que los de la segunda. Si pudierais dar un ejemplo de más o menos como funciana sería de gran ayuda.

Steven R. Davidson
2011-10-22 23:04:47

Hola Carlitos,

Tienes razón en que el ejercicio #3 no tiene sentido. De hecho, no debería aparecer, porque nos equivocamos en su diseño, así que sáltatelo. Intentaremos pensar en otro problema.

Disculpa la confusión que pudiéremos provocar.

Steven

Pedro
2011-12-21 23:02:41

Hola, tengo una duda, intentaba hacer un:

cin << entrada[x].dia

siendo entrada[x].dia un campo de bits, y me da error al compilar, pero si uso una variable intermediaria para el proceso, lo puedo compilar y funciona.

¿Por que no puedo hacer directamente el cin << entrada[x].dia, pese a encontrar la manera de hacerlo, me gustaria comprender el motivo por el que no me ha dejado?

Gracias de antemano

Héctor
2012-11-24 02:29:02

Bueno, aquí les dejo mi programa del ejercicio 1, por si le sirve a alguien de ejemplo:

#include <iostream>
using namespace std;

char arr[30], *pA;
int LongitudCadena(char* pA);

void main()
{
	pA = arr;
	cout<< "Ingrese su cadena:";
	cin.getline(arr, 30);
	cout<< "La cadena tiene: " << 	LongitudCadena(pA) << " Caracteres\n\n";
	system("pause");
}

int LongitudCadena(char *pB)
{
	int numA=0;
	while(*pB)
	{
		pB++;
		numA++;
	}
	return numA;
}

Saludos ;)

SimonUtn
2013-05-25 04:58:31

Yo resolvi el problema 1 con el programa de mas abajo.. Me gustaria saber algo.. No existe alguna forma de no tener que declarar el limite del arreglo cadena[x] (siendo x el limite) por el cual el compilador reserva el espacio de memoria para dicho arreglo, y trabajar solamente con un puntero de modo que el usuario pueda ingresar una cadena por teclado, y solo se use para almacenarla el espacio de memoria correspondiente a la cantidad de caracteres que posee la cadena ingresada? Pregunto esto porque a mi me gusta programar economizando al maximo la memoria, jaja.

Esta es mi resolucion:

( Uso puts y printf en vez de cout solo porque en la universidad me estan enseñando c y estoy mas acostumbrado)


#include <conio.h>
#include <stdio.h>

int LongitudCadena(char*); \\ funcion que devuelve la longitud de la cadena ingresada   
void LeeCadena(char[]);    \\ funcion que lee una cadena hasta que se apriete enter de como maximo 19 caracteres, y asigna el \0 al final.



int main()
{
char cadena[20];
char *pCad;


pCad=&cadena[0];    \\asigno a pcad la direccion de memoria del primero elemento del arreglo cadena
puts("ingrese cadena");
LeeCadena(cadena);    \\ leo la cadena                         
printf("La longitud de la cadena es %d", LongitudCadena(pCad)); \\ muestro su longitud utilizando la funcion LongitudCadena 
   
getche();  \\ para que la pantalla no se cierre automaticamente
return 0;  
}

void LeeCadena(char cadena[])
{
char c;    
int i=0;    

while(((c=getchar())!='\n')&&(i<19)) {
                                     cadena[i]=c;
                                     i++;
                                     }
cadena[i]='\0';   
}



int LongitudCadena(char *pCad)
{
int i=0;

while(*pCad!='\0') {
                    i++;            
                    pCad++;
                    }                
return i;
}

Ya que estoy quiero felicitarlos por la pagina Es excelente! . Estoy en segundo año ingenieria en sistemas y me sirvio mucho para consolidar ciertas cosas y para ir adelantando temas, porque por ej en la universidad todavia no dimos punteros pero ya aprendi o obtuve una base bastante buena con la ayuda de ustedes.

Salvador Pozo
2013-05-28 17:46:08

Hola Simón.

Vamos por partes.

Primero, el enunciado dice que se debe aplicar aritmética de punteros para calcular la longitud de la cadena. Tu has usado un entero para calcular la longitud, aunque uses aritmética de punteros para encontrar el final de la cadena.

Segundo, con respecto a la pregunta. Existen mecanismos en C++ para no tener que limitar el tamaño de la cadena, por ejemplo, usar la clase string.

Sin embargo, la clase usa internamente un buffer para almacenar la cadena en formato C, es decir, un array de char terminado en nulo, y lo agranda o encoge en función de la longitud de la cadena, de modo que no es una forma de ahorrar recursos.

El problema que planteas es complicado de solucionar, ya que siempre debemos leer la cadena al menos una vez, y para esa vez tenemos que estar seguros de que tenemos espacio suficiente para almacenarla.

Estamos en una etapa de C++ bastante básica todavía, y no prestamos atención a ciertos detalles, pero en un programa serio, esta forma de leer datos no es aceptable. Debemos asegurarnos siempre, por ejemplo, de que no se sobrepasa el tamaño de una cadena cuando se lee o se procesa.

Está bien economizar recursos, pero todo tiene un límite, y siempre hay que establecer algún compromiso a la hora de dimensionar cadenas.

Gracias por tu mensaje, y me alegra saber que la página te resulta útil.

Hasta pronto.

jordi
2013-06-21 12:32:27

No llego a entender para que se supone que tengo que usar punteros, si cualquier programa que aparece se hace = con punteros o sin punteros, realmente no hay ninguna diferencia.

Bueno, esta es mi solucion del ejercicio 1 y 2 haber que os parece:

Ejercicio1:

#include <stdio.h>

#include <stdlib.h>

//CALCULAR LONGITUD CADENA

int main()

{

char *cadena = "hola";

char *letra = "l";

int i;

int longitud=0;

for (i=0;i<5;i++)

{

if (cadena[i]!='\n')

{

longitud++;

}

}

printf ("%i ", longitud);

system("PAUSE");

}

Ejercicio2:

#include <stdio.h>

#include <stdlib.h>

int main()

{

char cadena[5] = "hola";

char *letra = "l";

int i;

for (i=0;i<5;i++)

{

if (cadena[i]==*letra)

{

printf ("%i ", i+1);

}

}

system("PAUSE");

}

sebastian
2013-07-23 21:35:42

hola,estoy intentando hacer el primer problema del capitulo 12 de punteros. tengo este problema:

esta es la sintaxis de la funcion:

int LongitudCadena (char *pcadena) {

int cantidad=0;

char c=0;

for(int a=0;a<M;a++){

if(pcadena!=0){

pcadena++;

cantidad++;

} else {

return 0;

}

}

return cantidad;

}

siempre retorna 20 que es el largo del array, obviamente en main esta asignado e puntero al array de este forma (pcadena = cadena;). espero respuesta. saludos!!

Andrés Camilo Sierra Hormiga
2013-10-03 14:14:20

Amigos, porfín pude hacer el primer ejercicio del de PUNTEROS::MENORIA DINÁMICA..... me quedó asi:

#include <iostream>
using namespace std;

int LongitudCadena(char *p){
	int contador = 0;
	
	while(*p != '\0'){
		contador++;
		*p++;
	}
	return contador;
}

int main(){
	char word[] = "holasss";
	
	cout<<LongitudCadena(word)<<endl;
	
	cout<<endl;
	cout<<"Press ENTER to exit >> ";
	getchar();
}
José Luis Coronel
2013-12-09 19:31:54

Hola a todos!

Me han quitado un poco de telarañas en la cabeza con este curso.

Pongo aqui mi solución del ejercicio 3.

#include <iostream>
using namespace std;
 
void mostrar(int numeros[], int cantidad)
{
  for (int i=0;i<cantidad;i++) cout << numeros[i] << " ";
  
  cout << endl; 
}

void Ordenar(int* vector, int nElementos, bool ascendente)
{
  int *ptLow, *ptHig;
  bool salida=false;
  int swap;
  do
  {
    // Inicializar posicion.
    ptLow = &vector[0];
    ptHig = &vector[nElementos-1];
    salida = false;
    while(!salida)
    {
      // Verificar el tipo de ordenamiento.
      if (ascendente)
      {
        if (*ptLow>*(ptLow+1))
        {
          // hacer el swap de ptLow
          swap = *ptLow;
          *ptLow=*(ptLow+1);
          *(ptLow+1)=swap;
          salida = true;
        }
        if (*ptHig<*(ptHig-1)) 
        {
          // hacer el swap de ptHig
          swap = *ptHig;
          *ptHig=*(ptHig-1);
          *(ptHig-1)=swap;
          salida = true;
        }
      }
      else
      {
        if (*ptLow<*(ptLow+1))
        {
          // hacer el swap de ptLow
          swap = *ptLow;
          *ptLow=*(ptLow+1);
          *(ptLow+1)=swap;
          salida = true;
        }
        if (*ptHig>*(ptHig-1)) 
        {
          // hacer el swap de ptHig
          swap = *ptHig;
          *ptHig=*(ptHig-1);
          *(ptHig-1)=swap;
          salida = true;
        }
      }
      // Si salida es verdadero no aumentar la posicion de los punteros
      if (!salida)
      {
        ptLow++;
        ptHig--;
      }
      // Se cruzan los punteros cuando el puntero Low es mayor que la posicion del puntero Hig.
      if ((ptHig-ptLow)<0) break;
    }
  } while ((ptHig-ptLow)>=0);
  return;
}

int main() 
{
  int numeros[] = { 35,2,9,68,5,67,8,66,74,26,56,89,87,90,34,86,22,3,50,4,27 };
  int *puntero;
  puntero = numeros;
  cout << "Datos que se van a ordenar\n";
  mostrar(numeros, (sizeof(numeros)/sizeof(numeros[0])));
  Ordenar(puntero, (sizeof(numeros)/sizeof(numeros[0])), true);
  cout << "Datos ordenados en forma ascedente\n";
  mostrar(numeros, (sizeof(numeros)/sizeof(numeros[0])));
  Ordenar(puntero, (sizeof(numeros)/sizeof(numeros[0])), false);
  cout << "Datos ordenados en forma descedente\n";
  mostrar(numeros, (sizeof(numeros)/sizeof(numeros[0])));
  return 0;
}

Saludos

Amado
2015-08-05 20:07:27

Para el problema 2 he realizado la solucion incluida, pero cuando acaba, el Visual Studio 2015RC me da error "Run-Time Check Failure #2 - Stack around the variable 'cadena' was corrupted." en una ventana, con opcion de interrumpir.

Os agradeceria me comentaseis la solucion y el error que obtengo del VS.

Un saludo.

#include <iostream>

using namespace std;

int BuscaCaracter(char *cad, char *car)
{
	for (int i = 0;;i++)
	{
		//cout << "cad(" << i << "):" << cad[i] << ", *car:" << *car;
		if (cad[i] == 'NULL') return -1;
		if (cad[i] == *car) return i;
	}
}


int main()
{
	char cadena[] = { NULL };
	char caracter = NULL;
	int retorno;
	
	cout << "\nCadena?\t:";cin.getline(cadena, 20);
	cout << "\nCaracter?\t;";cin >> caracter;
	
	retorno=BuscaCaracter(cadena, &caracter);
	switch (retorno) {
	case 1:cout << "\nPosicion\t:" << retorno+1;break;
	case -1:cout << "\nNo encontrado";
	}
	



	cout << endl;system("pause");
	return 0;
}
Amado
2015-08-05 20:12:27

Vaya, si defino cadena[] como cadena[20], no da error el VS. No puedo definir cadena[] sin determinar?.

Un saludo.

P.D.: Por cierto, tremendamente agradecido por la web, me sumo a todos los que os reconocen el esfuerzo.