alocare memorie

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
Post Reply
vili_c++
Junior
Junior
Posts: 20
Joined: 11 Feb 2014, 23:39
Judet: Dolj

alocare memorie

Post by vili_c++ » 20 Aug 2014, 21:46

Am nevoie de ajutor pentru codul de mai jos.
Codul afiseaza elementele unei matrici de [row*col] dimensiune cu row si col introduse de la tastatura.
Cand rulez codul facut cu malloc codul ruleaza perfect, in schimb cand rulez cu new codul nu mai functioneaza.
De ce ?

Code: Select all

#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    int row, col;
    cout << "\n Numbers of rows: ";
    cin >> row;
    cout << "\n Numbers of columns: ";
    cin >> col;
    cout << "\n col = " << col << endl;
    // int (*p)[col] = (int(*)[col])malloc(row * sizeof(*p));
    int (*p)[col] = (int(*)[col])new int*[row];
    for (int i=0; i<row; i++)
    {
        for (int j=0; j<col; j++)
        {
            cout << "\n tab[" << i << "][" << j << "] = ";
            cin >> *(*(p+i)+j);
        }
    }
    cout << endl;
    for (int i=0; i<row; i++)
    {
        for (int j=0; j<col; j++)
            cout << "\t\t" << *(*(p+i)+j);
        cout << endl;
    }
    // free (p);
    delete[] p;
    p = NULL;
    return 0;
}



Viorel
Microsoft MVP
Microsoft MVP
Posts: 292
Joined: 13 Jul 2007, 12:26

Re: alocare memorie

Post by Viorel » 21 Aug 2014, 08:28

Una din soluții:

Code: Select all

int * p = new int [row * col];

for( int i = 0; i < row; i++ )
{
	for( int j = 0; j < col; j++ )
	{
		cout << "tab[" << i << "][" << j << "] = ";
		cin >> p[col * i + j];
	}
}

cout << endl;

for( int i = 0; i < row; i++ )
{
	for( int j = 0; j < col; j++ )
	{
		cout << "\t\t" << p[col * i + j];
	}
	cout << endl;
}

delete [] p;

vili_c++
Junior
Junior
Posts: 20
Joined: 11 Feb 2014, 23:39
Judet: Dolj

Re: alocare memorie

Post by vili_c++ » 21 Aug 2014, 17:21

Multumesc de raspuns Viorel, dar eu vroiam sa stiu de ce codul respectiv mai exact liniile de cod urmatoare:
int (*p)[col] = (int(*)[col])malloc(row * sizeof(*p));
int (*p)[col] = (int(*)[col])new int*[row];
ruleaza cand memoria este alocata cu malloc, iar cand memoria este alocata cu new codul nu ruleaza.
Din ce am citit pe net stiu ca dimensiunea unui array trebuie cunoscuta in momentul compilarii, dar pana sa fie accesata linia de cod
int (*p)[col] = (int(*)[col])new int*[row] se cunosc variabilele col si row, deci dimensiunea este cunoscuta.
Si totusi, de ce codul nu ruleaza cu new ?
Alocarea memoriei cu malloc este diferita de alocarea memoriei cu new ? adica pentru malloc nu trebuie cunoscuta dimensiunea array-ului, in schimb pentru new trebuie ca dimensiunea sa fie cunoscuta, adica variabilele col si row sa fie constante ? (ptr ca asa cum spuneam mai sus si variabilele col si row se cunosc cand este accesata linia de cod int (*p)[col] = (int(*)[col])new int*[row])

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: alocare memorie

Post by bu7ch3r » 22 Aug 2014, 13:10

Code: Select all

int (*p)[col] 
Ai noroc ca-ti merge cu malloc. La compilare tu nu stii dimensiunea lui col. Probabil compilatorul iti da o adresa unde ai acces si merge, uneori. Cine stie. Comportamentul e ambiguu si pentru new si pentru malloc.
E loterie, poate compilezi pe debug si de asta; poate pe release crapa; poate pe release merge si cu new, poate cu mingw nu merge deloc si cu nmake merge mereu, n-ai cum sa-ti dai seama, nu e ceva ce poti controla...

Practic nu conteaza ca aloci cu new sau cu malloc - partea proasta e [col] ala. Un array static nu isi schimba dimensiunea la runtime. Poate tu il faci pe col ala 600000, iti dai seama ca n-o sa-ti redimensioneze nimeni array-ul ala.
Pentru valori mic poate merge dar mai incolo o sa-ti crape cand accesezi inafara stivei - si asta e doar un scenariu din multe altele care mai de care mai paranormale.

E ca si cum ai face:

Code: Select all

int a[n][m]; //compilatorul habar n-are cat e n si m dar e posibil ca "a" sa fie un array pe undeva pe acolo sau pur si simplu sa-ti puna o valoare default. El e cuminte si nu-ti spune, iti intoarce o adresa unde tu ai impresia ca ai 10000 de inti si     //defapt ai 100, sau nici macar. Nu mai zic ca array-ul asta iti sta tie pe stiva si oricand poti sa dai de gard si sa-ti crape programul...nici asta n-ai cum controla.
//Si mai fain e cand tu ai sa-l faci pe a[3][3]=30 si o sa observi ca si alta variabila isi schimba valoarea :) Sa vezi atunci ca malloc vs new o sa fie ultima ta problema.
Ideea e ca daca faci asa nu e bine:) N-are rost sa-ti bati capul atat timp cat int * p = new int [row * col]; e cea mai simpla solutie sau int * p = (int*)(row * col * sizeof(int)); sau sa le aloci pe rand asa cum se face la scoala...
Cu stima,
Lupu Claudiu

vili_c++
Junior
Junior
Posts: 20
Joined: 11 Feb 2014, 23:39
Judet: Dolj

Re: alocare memorie

Post by vili_c++ » 22 Aug 2014, 20:27

Multumesc pentru raspuns bu7ch3r !

Post Reply