2015-02-28 2 views
-1

Я пытаюсь выяснить динамическое распределение в C++, но у меня возникла проблема.Динамическое распределение памяти в C++

#include <stdio.h> 
#include <malloc.h> 

float *alocareV(int n) 
{ 
    float *v; 
    v = (float *)malloc(n*sizeof(float)); 
    return v; 
} 

float **alocareM(int m, int p) 
{ 
    float **a; 
    int i; 
    a = (float **)malloc(m*sizeof(float)); 
    for (i = 0; i < m; i++) 
     *(a + i) = (float *)malloc(p*sizeof(float)); 
    return a; 
} 

void dezalocareM(float **a ,int p) 
{ 
    int i; 
    for (i = 0; i < p; i++) 
     free (*(a + i)); 
} 

void citireV(float *v, int n) 
{ 
    int i; 
    for (i = 0; i < n; i++) 
    { 
     printf("v[%d]= ", i); 
     scanf_s("%f", *(v + i)); 
    } 
} 

void citireM(float **a, int m, int p) 
{ 
    int i, j; 
    for (i = 0; i < m;i++) 
    for (j = 0; j < p; j++) 
    { 
     printf("a[%d][%d]= ", i, j); 
     scanf_s("%f", *(*(a + i) + j)); 
    } 
} 

void main() 
{ 
    float *v=0, **a=0; 
    int n, m, p; 
    int i, j; 

    printf("n este egal cu "); 
    scanf_s("%d", &n); 
    printf("m este egal cu "); 
    scanf_s("%d", &m); 
    printf("p este egal cu "); 
    scanf_s("%d", &p); 

    alocareV(n); 
    alocareM(m, p); 

    citireV(v, n); 
    citireM(a, m, p); 

    free(v); 
    dezalocareM(a, p); 

} 

Во-первых, я должен был инициализировать * V = 0 и ** а = 0 в основном, потому что я получил ошибку говоря мне «неинициализированная локальные переменным используется». Если я не использовал подпрограммы, ошибка не появлялась. Во-вторых, после ввода 3 переменных (п, т, р) я получаю перестал работать коробку с проблемами Detalis существа:

Problem signature: 
    Problem Event Name: APPCRASH 
    Application Name: AlocareDinamica.exe 
    Application Version: 0.0.0.0 
    Application Timestamp: 54f1d7f9 
    Fault Module Name: AlocareDinamica.exe 
    Fault Module Version: 0.0.0.0 
    Fault Module Timestamp: 54f1d7f9 
    Exception Code: c0000005 
    Exception Offset: 00014059 
    OS Version: 6.3.9600.2.0.0.768.100 
    Locale ID: 1033 
    Additional Information 1: 5861 
    Additional Information 2: 5861822e1919d7c014bbb064c64908b2 
    Additional Information 3: a10f 
    Additional Information 4: a10ff7d2bb2516fdc753f9c34fc3b069 

Может кто-то пожалуйста, помогите? Спасибо

+1

Это больше похоже на c, чем на C++. В C++ у нас есть [управление динамической памятью] (http://en.cppreference.com/w/cpp/memory) и [контейнерные классы] (http://en.cppreference.com/w/cpp/container). –

+0

'a = (float **) malloc (m * sizeof (float));' вы используете 'sizeof (float)', когда вы должны использовать 'sizeof (float *)' – emlai

+0

Также у вас есть утечка памяти, поскольку 'dezalocareM' не освобождает массив указателей float. И вы освобождаете неправильное количество массивов с плавающей запятой в 'dezalocareM', потому что вы зацикливаете до' p', когда вы должны зацикливаться на 'm'. – emlai

ответ

1

Прежде всего, обратите внимание, что ваш вопрос имеет мало общего с C++. Насколько я понимаю, это полностью C. В C++ вы использовали бы new вместо malloc для редких случаев, в которых вы имеете дело с низкоуровневой операцией памяти и такими классами, как std::string или std::vector для более высоких уровней.

Однако, давайте посмотрим, что здесь не так.

Наиболее очевидной проблема заключается в том, что нет никакой связи между тем, что происходит в alocareV и то, что происходит в citireV, то же самое для alocareM/citireM. Результат ваших функций распределения отбрасывается. Вы должны использовать результаты:

v = alocareV(n); 
a = alocareM(m, p); 

Существует также ошибка в alocareM. Когда вы выделяете память для двойного указателя, вы должны использовать sizeof(float*), а не sizeof(float).

Следующая ошибка в citireV. scanf_s требует, чтобы вы указали указатель на объект, на который нужно записать. *(v + i), однако, дает float, а не float*, потому что вы разыскиваете указатель. Правильный вызов будет:

scanf_s("%f", (v + i)); 

citireM имеет точно такую ​​же ошибку. Правильный вызов должен быть:

scanf_s("%f", (*(a + i) + j)); 

Наконец, main должен вернуть int. void main не является законным в C или C++.

Это должно исправить.

+0

_ «В C++ вы бы использовали новый», я сильно не согласен. См. Мой комментарий к вопросу, что должно использоваться в C++. –

+0

@ πάνταῥεῖ: Умные указатели не заменяют * все * использует для сырых указателей. И все-таки они реализованы в терминах «нового». Я рассматриваю их классы более высокого уровня, такие как 'std :: vector' или' std :: string'. Я думаю, что самое главное для начинающих C++, исходящих из Java или подобных языков, - это узнать, что они могут создавать любой объект в стеке и даже не требуют динамического распределения памяти во всем мире. –

+0

@ πάνταῥεῖ: И вообще я говорил о «редких случаях»! :) –

0

Правильный код должен быть:

#include <stdio.h> 
#include <malloc.h> 

float *alocareV(int n) 
{ 
    float *v; 
    v = (float *)malloc(n*sizeof(float)); 
    return v; 
} 

float **alocareM(int m, int p) 
{ 
    float **a; 
    int i; 
    a = (float **)malloc(m*sizeof(float *)); 
    for (i = 0; i < m; i++) 
     *(a + i) = (float *)malloc(p*sizeof(float)); 
    return a; 
} 

void dezalocareM(float **a ,int p) 
{ 
    int i; 
    for (i = 0; i < p; i++) 
     free (*(a + i)); 
} 

void citireV(float *v, int n) 
{ 
    int i; 
    for (i = 0; i < n; i++) 
    { 
     printf("v[%d]= ", i); 
     scanf_s("%f", (v + i)); 
    } 
} 

void citireM(float **a, int m, int p) 
{ 
    int i, j; 
    for (i = 0; i < m;i++) 
    for (j = 0; j < p; j++) 
    { 
     printf("a[%d][%d]= ", i, j); 
     scanf_s("%f", (*(a + i) + j)); 
    } 
} 

void main() 
{ 
    float *v=0, **a=0; 
    int n, m, p; 
    int i, j; 

    printf("n este egal cu "); 
    scanf_s("%d", &n); 
    printf("m este egal cu "); 
    scanf_s("%d", &m); 
    printf("p este egal cu "); 
    scanf_s("%d", &p); 

    v = alocareV(n); 
    a = alocareM(m, p); 

    citireV(v, n); 
    citireM(a, m, p); 

    free(v); 
    dezalocareM(a, p); 

} 

Изменение

alocareV(n); 
alocareM(m, p); 

в главной функции:

v = alocareV(n); 
a = alocareM(m, p); 

Также изменили аргументы функции scanf_s. Надеюсь, что это поможет вам.

+0

Вы должны объяснить это немного. Особенно укажите, что вы изменили. – emlai

+0

... и в этом смысле это код _ideal_ для C++. –

+0

@ πάνταῥεῖ: Его код имеет ошибку. Я только что исправил это. – Sumeet

Смежные вопросы