operador new para doble char

Iniciado por neo_from_cs_matrix, 7 Agosto 2011, 23:58 PM

0 Miembros y 1 Visitante están viendo este tema.

neo_from_cs_matrix

tengo asi:

char** descircion;

dentro de la clase, y en el constructor necesito asignarle las dimensiones a esta matriz charesca. iba a hacerlo con malloc que es coo yo se hacerlo pero me dijeron que sea hecho con new y delete, pero para vector de int sabia como usarlo pero para este caso no. ocea necesitaria un new y un delete para esa matriz de char, si alguno sabe  :rolleyes:

escabe

Con esto creas un array de tres punteros a punteros tipo char:

    char **A = new char*[3];
    A[0] = "uno";
    A[1] = "dos";
    A[2] = "tres";
    delete [] A;


Si cada elemento lo quieres crear dinámicamente tendras que volver a usar el operador new:

   A[0] = new char[10];

No te olvides de su destrucción.

La forma estática es simple:

   char A[3][4];


Saludos.

neo_from_cs_matrix


este es una demostrasion de mi clase que estoy haciendo esto compila bien, pero decime si asi esta bien asignado con new y borrado con delete  :xD


class Producto
{
private:
int cantidad_items;
char** items_de_descripcion;
char descripcion[1000];
public:
Producto(int cantidad_items);
~Producto();// no pueden tener argumentos
};





Producto::Producto(int items=5)
{
cantidad_items = items;

int capacidad = 1000/cantidad_items;
//items_de_descripcion = (char**) new char[cantidad_items][capacidad];
items_de_descripcion = new char*[cantidad_items];

int a=0;
while(a<cantidad_items)
{
items_de_descripcion[a]=new char[capacidad];
a++;
}
}

Producto::~Producto()
{
for(int i = 0; i < cantidad_items; i++)   // Paso 1: Borrar columnas
delete [] items_de_descripcion[i];
delete [] items_de_descripcion;   // paso 2: borrar filas
}




escabe

La filosofía es correcta pero me llama la atención esto:
int capacidad = 1000/cantidad_items;

Si por defecto cantidad_items es 5 las cadenas van a tener longitud cero...

¿Quizás querías decir?
int capacidad = 1000*cantidad_items;


Saludos.

neo_from_cs_matrix

no, las cadenas van a tener longitud 1000/la cantidad de cadenas.
como por defecto la cantidad es 5, entonces 1000 dividido 5 = 200

yo lo que quisiera saber es porque siendo memoria dinamica no permite usar asi

items_de_descripcion = (char**) new char[cantidad_items][capacidad];

porque tira errores de que las dimensiones no son constantes.
pero asiendo eso con malloc si lo acepta. pero porque con new no?


escabe

Cita de: neo_from_cs_matrix en  8 Agosto 2011, 19:07 PM
yo lo que quisiera saber es porque siendo memoria dinamica no permite usar asi

items_de_descripcion = (char**) new char[cantidad_items][capacidad];

porque tira errores de que las dimensiones no son constantes.
pero asiendo eso con malloc si lo acepta. pero porque con new no?

Esa sintaxis no es válida. Al asignar primero espacio para los punteros a las cadenas, la memoria no va a ser contínua y debes asignar espacio, despues, para cada cadena.

Puedes realizar una reserva global con new, igual que con malloc.
items_de_descripcion = (char**) new char[cantidad_items * capacidad + cantidad_items * sizeof(char*)];

Luego asignas los valores de los punteros (al inicio del espacio de la memoria localizada) a la dirección de las cadenas que vendrán una detrás de otra en la posición  items_de_descripcion + cantidad_items * sizeof(char*);

Esto se puede hacer pero es mas lioso, difícil de entender y de leer mas adelante...

Saludos.

neo_from_cs_matrix

Cita de: escabe en  8 Agosto 2011, 19:43 PM
Esa sintaxis no es válida. Al asignar primero espacio para los punteros a las cadenas, la memoria no va a ser contínua y debes asignar espacio, despues, para cada cadena.

Puedes realizar una reserva global con new, igual que con malloc.
items_de_descripcion = (char**) new char[cantidad_items * capacidad + cantidad_items * sizeof(char*)];

Luego asignas los valores de los punteros (al inicio del espacio de la memoria localizada) a la dirección de las cadenas que vendrán una detrás de otra en la posición  items_de_descripcion + cantidad_items * sizeof(char*);

Esto se puede hacer pero es mas lioso, difícil de entender y de leer mas adelante...

Saludos.

osea lo que hacia con malloc si se que era una asignacion global, osea el tamanio total de la matriz. pero pense que con esa forma de new (la que no compila) era tambien asignacion global PARA una matriz.

pero ahora segun observo
items_de_descripcion = (char**) new char[cantidad_items * capacidad + cantidad_items * sizeof(char*)];

esto asignaria el tamaño total de la matriz pero de forma contigua, es esto asi ?

y explicame otra cosa, esto
Citar
.... Al asignar primero espacio para los punteros a las cadenas, la memoria no va a ser contínua y debes asignar espacio, despues, para cada cadena.
.....

entiendo que inclusive el compilador no acepta de otra forma, pero porque esa necesidad de hacerlo asi, osea primero los 5 punteros y despues los vectores de cada uno

si puedes contestarme esas dos preguntas te lo agradeceria me has ayudado a entender, gracias ;)


escabe

Cita de: neo_from_cs_matrix en  8 Agosto 2011, 23:37 PM
osea lo que hacia con malloc si se que era una asignacion global, osea el tamanio total de la matriz. pero pense que con esa forma de new (la que no compila) era tambien asignacion global PARA una matriz.

pero ahora segun observo
items_de_descripcion = (char**) new char[cantidad_items * capacidad + cantidad_items * sizeof(char*)];

esto asignaria el tamaño total de la matriz pero de forma contigua, es esto asi ?
Eso asigna tamaño para los puteros y la matriz en memoria contigua.

Cita de: neo_from_cs_matrix en  8 Agosto 2011, 23:37 PM
y explicame otra cosa, esto
Citar.... Al asignar primero espacio para los punteros a las cadenas, la memoria no va a ser contínua y debes asignar espacio, despues, para cada cadena.
.....
entiendo que inclusive el compilador no acepta de otra forma, pero porque esa necesidad de hacerlo asi, osea primero los 5 punteros y despues los vectores de cada uno

si puedes contestarme esas dos preguntas te lo agradeceria me has ayudado a entender, gracias ;)

El uso de new tal como se muestra mas arriba es equivalente a el uso de cualquier función que localice memoria. Una vez obtenido el bloque de memoria necesario, somos nosotros los que vamos a decidir donde estarán los punteros a las cadenas y donde estarán éstas. Como es mas fácil definir que tenemos todos los punteros al principio, así lo propongo. De ese modo al referirnos a un puntero que apunte al principio del bloque, su contenido será el primer puntero... Por similitud al significado de un array en C ( un array se define por un puntero al primer elemento del mismo). Pero en esto no tiene nada que ver el compilador, aunque si la convención de C/C++.  Tu puedes hacerlo de otra forma, incluso sin pos punteros a las cadenas, pues si todas ellas tienen el mismo tamaño, las puedes localizar sin necesidad de una tabla o array de punteros previo.

En esto del manejo de la memoria y punteros el C/C++ es un campeón  :D

No se si me explico o te lío mas.

Saludos.