двойное освобождение или повреждение (выход) при освобождении памяти в c ++ - PullRequest
0 голосов
/ 05 марта 2019

У меня есть функция, которая возвращает двумерный массив в c ++ следующим образом

float** Input_data(float** train_data, int Nv, int N){
float** x_train=new float*[Nv];

int a = 0,b = 0;
for(a = 1;a<= Nv;a++){

    x_train[a] = new float[N+1];

    for(b = 1; b <= N+1; b++){
        if(b == 1){

            x_train[a][b] = 1;

        }else{

        x_train[a][b] = train_data[a][b-1];

        }
    }return x_train;}

цель приведенного выше кода - добавить единицы в первый столбец и добавить оставшиеся данные из указателя train_data в x_train.после обработки и использования x_train я пытаюсь освободить x_train следующим образом

void destroyx_array(float**x_train,int Nv){

for (int free_x = 1;free_x <= Nv;free_x++){
delete[] x_train[free_x];}delete[] x_train;}

и вызываю функцию уничтожения следующим образом

destroyx_array(x_train,Nv)

функции Input_data работают нормально, но когда я пытаюсь уничтожить его_x_arrayдает мне двойную свободу или коррупция (вне) прервана (ядро сброшено) кто-нибудь может объяснить, что я не так делаю?спасибо

1 Ответ

0 голосов
/ 05 марта 2019

Проще говоря, ваш код повреждает память.Лучше всего не использовать необработанные указатели, а вместо этого использовать контейнерные классы, такие как std::vector.

Сказав это, чтобы исправить свой текущий код, проблема заключается в том, что вы пишете за пределами памятиздесь:

for(a = 1;a<= Nv;a++)

когда a == Nv, вы пишете одну «строку» сверх того, что было выделено.Это похоже на проявление попытки подделать массивы на основе 1.Массивы в C ++ начинаются с 0, а не с 1. Попытка подделать массивы на основе 1 неизменно может привести к ошибкам и повреждению памяти.

Исправление состоит в том, чтобы переписать функцию так, чтобы она начиналась с 0, а не с 1, и обеспечитьцикл повторяется до n-1, где n - общее количество строк:

for (a = 0; a < Nv; ++a)


цель приведенного выше кода состоит в том, чтобы добавить их впервый столбец и добавьте оставшиеся данные из указателя train_data в x_train

Вместо цикла, который вы написали для проверки первого столбца, вы можете упростить это, просто используя memcpy:

 for (int i = 0; i < Nv; ++i)
 {
     x_train[i][0] = 1;
     memcpy(&x_train[i][1], &train_data[i][0], N * sizeof(float));
 }  

Таким образом, вся функция будет выглядеть так:

float** Input_data(float** train_data, int Nv, int N)
{
    float** x_train=new float*[Nv];
    for(int a = 0; a < Nv; a++)
       x_train[a] = new float[N+1];
    for (int a = 0; a < Nv; a++)
    {
       x_train[i][0] = 1;
       memcpy(&x_train[i][1], &train_data[i][0], N * sizeof(float));
    } 
    return x_train;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...