Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос про 2 мерные указатели 
:(
    Опции темы
djezul
Дата 3.7.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Вот код -
Код

#include <iostream>
#include <windows.h>
#include <clocale>
#include <cstdio>
#include <cstring>
#include <conio.h>
using namespace std;
//==================
void menu();
void add();
void output();
//==================
char **p;
int N;    //Количество элементов!
int is = false;    //Существует ли массив!
//==================
void main(){
    setlocale(LC_CTYPE,"RUSSIAN");
    //============================
    bool exit = false;
    int querry;
    //============================
    while (!exit){
        menu();
        cin >> querry;
        switch (querry) {
            case 1:
                system("CLS");
                add();
                break;
            case 2:
                system("CLS");
                if(is){

                }else{
                    cout << "Нету массива!";
                    Sleep(2000);
                    system("CLS");
                }    
                break;
            case 3:
                if(is){

                }else{
                    cout << "Нету массива!";
                    Sleep(2000);
                    system("CLS");
                }    
                break;
            case 4:
                system("CLS");
                output();
                while ( !_kbhit() ) Sleep(10);
                break;
            case 0:
                exit = true;
                break;
        }
    }    
}
void add(){
    char surname[100];
    if(is){
        int kol;
        cout << "Сколько записей добавить?\n\n\t>>> ";
        cin >> kol;
        cout << "\n\n";
        char **q;
        q = new char*[N + kol];
        for ( int i = 0 ; i < N ; i++ ){
            q[i] = p[i];    
            strcpy( q[i] , p[i] );
        }
        for ( int i = N , j = 1 ; i < N + kol ; i++ , j++ ){
            cout << "Введите " << j << " фамилию!\n";
            cin >> surname;
            q[i] = new char[strlen(surname)+1];
            strcpy( q[i] , surname );
            cout << "\n";
        }
        for ( int i = 0 ; i < N ; i++ ) delete[] p[i]; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        delete[] p;
        p = NULL;
        N = N + kol;
        p = new char*[N];
        for (int i = 0 ; i < N ; i++ ){
            p[i] = q[i];
            strcpy( p[i] , q[i] );
        }
        for ( int i = 0 ; i < N ; i++ ) delete[] q[i];
        delete[] q;
        q = NULL;
    }else{
        cout << "Сколько записей добавить?\n\n\t>>> ";
        cin >> N;
        cout << "\n\n";
        p = new char*[N];
        for (int i = 0 ; i < N ; i++ ) {
            cout << "Введите " << i << " фамилию!\n";
            cin >> surname;
            p[i] = new char[strlen(surname)+1];
            strcpy( p[i] , surname );
            cout << "\n";
        }
        is = true;
    }
}
void menu(){
    system("CLS");
    cout << "Выберите действие!\n"
         << "1 - Добавить\n"
         << "2 - Сортировать\n"
         << "3 - Удалить\n"
         << "4 - Вывести\n"
         << "0 - Выход\n\n\t>>> ";
}
void output(){    
    for (int i = 0 ; i < N ; i++){
        cout << p[i] << "\n";    
    }
}

По нему есть несколько вопросов.
1 - что это за ошибка - 
user posted image
Какова причина её возникновения ? И как её исправить ?
И почему , там где я поставил <<<<< удаляется и q  , а не только p , как удалить только p ?
Прога , думаю и так понятно , но всё же скажу , должна создавать динамический массив с возможностью добавления. С 1 мерными у меня всё работает  , но так почему то нет .
PM MAIL ICQ Skype   Вверх
zim22
Дата 3.7.2009, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(djezul @  3.7.2009,  16:19 Найти цитируемый пост)
Какова причина её возникновения ? И как её исправить ?

скорей всего вы пишете либо за пределы массива либо удаляете статический массив.


--------------------
PM MAIL   Вверх
djezul
Дата 3.7.2009, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



ну по коду должно быть видно , что массив не статический, и за пределы вроде не вылетаю, тем более пишет , что в  52 строке , причем здесь она, никак не пойму.
PM MAIL ICQ Skype   Вверх
Albor
Дата 3.7.2009, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



При копировании массива (add()) копируются указатели p[i]=q[i]; затем массив q удаляется, соответственно все указатели массива p  становятся недействительными. Копируя массив, копируй только содержимое, а указатели не трогай, в каждом массиве свои.

Это сообщение отредактировал(а) Albor - 3.7.2009, 16:54
PM MAIL ICQ   Вверх
zim22
Дата 3.7.2009, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(djezul @  3.7.2009,  16:39 Найти цитируемый пост)
, тем более пишет , что в  52 строке

какого файла? не вашего.


--------------------
PM MAIL   Вверх
djezul
Дата 3.7.2009, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(zim22 @  3.7.2009,  18:37 Найти цитируемый пост)
какого файла? не вашего.

В том то и дело , что этого)

PM MAIL ICQ Skype   Вверх
Albor
Дата 4.7.2009, 06:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



djezul, ты сам писал код? Если да, то должен понимать что написано. Что такое p[i] и q[i] - это указатели на char. Смотри, для q[i] ты делаешь следующее:
Код

q[i] = new char[strlen(surname)+1];
            strcpy( q[i] , surname );

После этого q[i] указывает на область памяти, куда скопирована строка из surname. Дальше удаляется и вновь создаётся с новым размером массив p - нормально. Но дальше... что делает строка p[i]=q[i]? Ты просто копируешь указатель, после этого оба массива указывают на одни и те же данные, а строчка strcpy( p[i] , q[i] );? - посмотри в дебаге что ты копируешь и куда, указатели-то одинаковые, но это пол-беды (скажем даже не совсем беда, может у программера такой каприз smile ). Но,вот дальнейшее удаление массива что делает? Правильно - освобождает память, выделенную под массив. Строка delete[] q[i]; освобождает участок, куда указывает p[i]. Всё, p[i] нельзя использовать! Потому аварийные окна выбрасываются (скорее не аварийные а информирующие о возможной аварии. Если скомпилишь релиз, то этого окна не увидишь, и программа будет работать, только сюрпризы будут smile ). Правильно было бы написать вместо p[i]=q[i] следующее:
Код

p[i] = new char[strlen(q[i])+1];
            strcpy( p[i] , q[i] );

тогда p[i]  уже не зависит от q[i].

Это сообщение отредактировал(а) Albor - 4.7.2009, 06:27
PM MAIL ICQ   Вверх
djezul
Дата 4.7.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Albor, спасибо , я врубился в это ещё после твоего 1 поста))) просто я ж говорю , при написании подобной проги только с 1 мерным массивом указетелей, так прокатывало , поэтому решил и тут так сделать) теперь понял , что это неправильно . Твой вариант работает , спасибо)
P.S. код писал сам))


Это сообщение отредактировал(а) djezul - 4.7.2009, 16:01
PM MAIL ICQ Skype   Вверх
zim22
Дата 4.7.2009, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(djezul @  4.7.2009,  15:54 Найти цитируемый пост)
 , что необработаное исключение в этой строке

new кидает exception, когда не может выделить память


--------------------
PM MAIL   Вверх
djezul
Дата 4.7.2009, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



zim22, Спасибо , буду знать)
PM MAIL ICQ Skype   Вверх
djezul
Дата 4.7.2009, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



А как правильно сделать сортировку , мне нужно допустим по алфавиту отсортировать фамилии, вот я пытаюсь так 
Код

void sort(){
    char *temp;
    for (int k = 0 ; k < N ; k++ ){
        for (int i = 0 ; i < N ; i++ )
            if ( p[i] < p[i+1] ){
                temp = new char[strlen(p[i]) + 1];
                strcpy( temp , p[i] );
                delete[] p[i];
                p[i] = new char[strlen(p[i + 1])+1];
                strcpy( p[i] , p[i + 1] );
                delete[] p[i + 1];
                p[i + 1] = new char[strlen(temp)+1];
                strcpy( p[i + 1] , temp );
                delete[] temp;
            }
    }
}

НО , так не работает , почемуто не хочет выделять достаточно памяти для p[i]  , хотя я вроде еёудаляю , и создаю с необходимым количеством((( В чём тут ошибка?
PM MAIL ICQ Skype   Вверх
zim22
Дата 4.7.2009, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(djezul @  4.7.2009,  19:06 Найти цитируемый пост)
 В чём тут ошибка?

используйте std::sort или qsort


--------------------
PM MAIL   Вверх
djezul
Дата 4.7.2009, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



zim22, не просто хочу научится работе с указателями) то понятно.
PM MAIL ICQ Skype   Вверх
zim22
Дата 4.7.2009, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(djezul @  4.7.2009,  20:27 Найти цитируемый пост)
, не просто хочу научится работе с указателями) 

почитайте тогда книгу Б.Кернигана, Д.Ритчи "Язык программирования С". Глава 5 "Указатели и массивы". 


--------------------
PM MAIL   Вверх
Soah
Дата 4.7.2009, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  4.7.2009,  19:06 Найти цитируемый пост)

for (int i = 0 ; i < N ; i++ )            
    if ( p[i] < p[i+1] ){ // <- 1. выход за пределы массива
                          //    2. для сравнения строк используйте функцию strcmp()


strcmp
PM MAIL   Вверх
djezul
Дата 4.7.2009, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



zim22, Читал, и не только Б.Кернигана, Д.Ритчи , и Шилдта читал, но всё равно непонятно , почему не работает .

Soah, а зачем мне сравнивать строки, по тому коду , что я привел выше, поидее должно в переменную темп выделяться памяти , как раз сколько сколько надо . Кстати потом дописал только что , пишу ещё temp = NULL;  , но всё равно не помогает , да и если я буду делать такую проверку, каким мне ещё способом перемещать по тому адресу содержимое p[i] , если не так как я сделал?
PM MAIL ICQ Skype   Вверх
Soah
Дата 4.7.2009, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  4.7.2009,  22:39 Найти цитируемый пост)
а зачем мне сравнивать строки

а что же Вы сравниваете?

Цитата(djezul @  4.7.2009,  22:39 Найти цитируемый пост)
но всё равно не помогает

Цитата(Soah @  4.7.2009,  21:18 Найти цитируемый пост)
if ( p[i] < p[i+1] ){ // <- 1. выход за пределы массива

PM MAIL   Вверх
djezul
Дата 4.7.2009, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Soah, а всё врубился , спасибо , а то просто дебагер показывал вылет 3 строками ниже )))
Неа , не помогло , все равно вылет в этой строке показует 
Код

p[i] = new char[strlen(p[i + 1])+1];


Добавлено через 4 минуты и 46 секунд
Вот изменил код немного 
Код

void sort(){
    char *temp;
    for (int k = 0 ; k < N ; k++ ){
        for (int i = 0 ; i < N ; i++ )
            if ( strcmp( p[i] , p[i+1] ) > 0 ){
                temp = new char[strlen(p[i]) + 1];
                strcpy( temp , p[i] );
                delete[] p[i];
                p = NULL;
                p[i] = new char[strlen(p[i + 1])+1];
                strcpy( p[i] , p[i + 1] );
                delete[] p[i + 1];
                p[i + 1] = NULL;
                p[i + 1] = new char[strlen(temp)+1];
                strcpy( p[i + 1] , temp );
                delete[] temp;
                temp = NULL;
            }
    }
}


Это сообщение отредактировал(а) djezul - 4.7.2009, 23:02
PM MAIL ICQ Skype   Вверх
Soah
Дата 4.7.2009, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  4.7.2009,  22:58 Найти цитируемый пост)
а всё врубился

Цитата(djezul @  4.7.2009,  22:58 Найти цитируемый пост)
Код

for (int i = 0 ; i < N ; i++ )

Если i = N-1, сколько будет i+1?
Правельно i+1 = N, p[N] - выход за пределы массива

Цитата(djezul @  4.7.2009,  22:58 Найти цитируемый пост)
 p = NULL;

и что делает эта строчка?
PM MAIL   Вверх
djezul
Дата 5.7.2009, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Soah, 
Цитата(Soah @  4.7.2009,  23:18 Найти цитируемый пост)
Если i = N-1, сколько будет i+1?
Правельно i+1 = N, p[N] - выход за пределы массива

Немного не понял, это к какому месту кода? В сортировки такого нет(
PM MAIL ICQ Skype   Вверх
Soah
Дата 5.7.2009, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



djezul, я уже устал цитировать этот код

Цитата(djezul @  4.7.2009,  22:58 Найти цитируемый пост)

for (int i = 0 ; i < N ; i++ )            
    if ( strcmp( p[i] , p[i+1] ) > 0 ){ // <- вот здесь


PM MAIL   Вверх
djezul
Дата 5.7.2009, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Soah, 
Цитата(Soah @  5.7.2009,  00:37 Найти цитируемый пост)
я уже устал цитировать этот код

Цитата(djezul @  4.7.2009,  22:58 Найти цитируемый пост)

for (int i = 0 ; i < N ; i++ )            
    if ( strcmp( p[i] , p[i+1] ) > 0 ){ // <- вот здесь


А что в нём не так ? Я исправил N на N + 1  ,  но ошибка не там возникает  , даже при написании N + 1 , ошибка вылетает тут 
Код

p[i] = new char[strlen(p[i + 1])+1];

PM MAIL ICQ Skype   Вверх
Soah
Дата 5.7.2009, 01:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  5.7.2009,  01:07 Найти цитируемый пост)
Я исправил N на N + 1

а почему так мало, давайте тогда уж N + 100

for (int i = 0 ; i < N ; i++ )
допустим N = 4
i = 0    i+1 = 1   -> p[0] и p[1]
i = 1    i+1 = 2   -> p[1] и p[2]
i = 2    i+1 = 3   -> p[2] и p[3]
i = 3    i+1 = 4   -> p[3] и p[4]

p[0]..p[4]  -> 5 элементов, но ведь N = 4
PM MAIL   Вверх
djezul
Дата 5.7.2009, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(Soah @  5.7.2009,  01:15 Найти цитируемый пост)
а почему так мало, давайте тогда уж N + 100

Не понял смысла этой фразы.

Цитата(Soah @  5.7.2009,  01:15 Найти цитируемый пост)

for (int i = 0 ; i < N ; i++ )

допустим N = 4

У меня так уже
Код

for (int i = 0 ; i < N + 1; i++ )

У тогда все ваши расчёты будут верны.

Цитата(Soah @  5.7.2009,  01:15 Найти цитируемый пост)
i = 0    i+1 = 1   -> p[0] и p[1]
i = 1    i+1 = 2   -> p[1] и p[2]
i = 2    i+1 = 3   -> p[2] и p[3]
i = 3    i+1 = 4   -> p[3] и p[4]


и N будет равно 5.
PM MAIL ICQ Skype   Вверх
Soah
Дата 5.7.2009, 01:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  5.7.2009,  01:41 Найти цитируемый пост)
for (int i = 0 ; i < N + 1; i++ )

можете обьяснить почему N+1?

Цитата(djezul @  5.7.2009,  01:41 Найти цитируемый пост)
и N будет равно 5.

но ведь изначально количество элементов 4.

Цитата(djezul @  5.7.2009,  01:41 Найти цитируемый пост)
тогда все ваши расчёты будут верны.

да?
N = 4
i < N +1  или i < 5
i = 0    i+1 = 1   -> p[0] и p[1]
i = 1    i+1 = 2   -> p[1] и p[2]
i = 2    i+1 = 3   -> p[2] и p[3]
i = 3    i+1 = 4   -> p[3] и p[4]
i = 4    i+1 = 5   -> p[4] и p[5]
p[0]..p[5]  -> 6 элементов, но ведь N = 4

смотрите, допустим у нас массив из 3 элементов, тогда
первый элемент сравниваем со вторым, второй с третьим -> два сравнения - две итерации

массив из 4 элементов, тогда
первый элемент сравниваем со вторым, второй с третьим,
третий с четвёртым -> три сравнения - три итерации
PM MAIL   Вверх
djezul
Дата 5.7.2009, 02:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Вы хотите сказать , что N нужно присваивать N - 1 , то есть так 
Код

for (int i = 0 ; i < N - 1; i++ )

Попробовал , та же ошибка в том же месте) 
PM MAIL ICQ Skype   Вверх
Soah
Дата 5.7.2009, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  5.7.2009,  02:08 Найти цитируемый пост)
Вы хотите сказать , что N нужно присваивать N - 1 , то есть так 

 smile 
но Вы хотя бы понимаете почему?

Цитата(djezul @  5.7.2009,  02:08 Найти цитируемый пост)
Попробовал , та же ошибка в том же месте) 

а я уже спрашивал
Цитата(djezul @  4.7.2009,  22:58 Найти цитируемый пост)

delete[] p[i];                
p = NULL;        // <- что делает эта строка?
p[i] = new char[strlen(p[i + 1])+1];


PM MAIL   Вверх
djezul
Дата 5.7.2009, 02:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(Soah @  5.7.2009,  02:13 Найти цитируемый пост)
но Вы хотя бы понимаете почему?

Да , спасибо , что так долго и упорно вдалбливали мне в голову , а не просто сказали что исправить)) 
А насчёт NULL , так препод сказал делать , правда в другой задаче, приводит к типу void * , а тут я впихнул , уже будучи в растеряности ))))
Ещё раз спасибо)
PM MAIL ICQ Skype   Вверх
djezul
Дата 5.7.2009, 02:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Код

void Delete(){
    int value;
    output();
    cout << "\n\nВведите номмер записи, которую необходимо удалить!\n\n\t>>> ";
    cin >> value;
    cout << "\n\n";
    char **q;
    q = new char*[N - 1];
    if ( value == 0 ){
        for ( int i = 1 ; i < N - 1 ; i++ ){
            q[i] = new char[strlen(p[i])+1];
            strcpy( q[i] , p[i] );
        }
    }else{
        for ( int i = 0 ; i < N - 1 ; i++ ){
            if ( i == value ) continue; 
            q[i] = new char[strlen(p[i])+1];
            strcpy( q[i] , p[i] );
        }
    }
    for ( int i = 0 ; i < N ; i++ )    delete[] p[i];
    delete[] p;
    N = N - 1;
    p = new char*[N];
    for ( int i = 0 ; i < N ; i++ ){
        p[i] = new char[strlen(q[i]) + 1];     //<<< Тут ошибка при 2 проходе
        strcpy( p[i] , q[i] );
    }
    for ( int i = 0 ; i < N ; i++ )    delete[] q[i];
    delete[] q;
}

Ну а здесь почему ошибка? smile  smile  smile  Ох уж эти указатели, всё им не так

Это сообщение отредактировал(а) djezul - 5.7.2009, 02:36
PM MAIL ICQ Skype   Вверх
Soah
Дата 5.7.2009, 21:50 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  5.7.2009,  02:35 Найти цитируемый пост)
Ну а здесь почему ошибка?

Цитата(djezul @  5.7.2009,  02:35 Найти цитируемый пост)

Код

// ...
q = new char*[N - 1]; // <-   N-1 элементов
// ...
for ( int i = 0 ; i < N ; i++ ){
    p[i] = new char[strlen(q[i]) + 1]; // <-   а тут уже обращаемся к N элементам
// ...



Цитата(djezul @  5.7.2009,  02:35 Найти цитируемый пост)
Ох уж эти указатели, всё им не так

указатели тут ни причём, надо правильно составлять алгоритмы и пользоваться отладчиком.

Это сообщение отредактировал(а) Soah - 5.7.2009, 21:53
PM MAIL   Вверх
djezul
Дата 6.7.2009, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(Soah @  5.7.2009,  21:50 Найти цитируемый пост)
// ...
q = new char*[N - 1]; // <-   N-1 элементов
// ...
for ( int i = 0 ; i < N ; i++ ){
    p[i] = new char[strlen(q[i]) + 1]; // <-   а тут уже обращаемся к N элементам
// ...

А как насчёт этой строки немного выше 
Код

N = N - 1;


PM MAIL ICQ Skype   Вверх
Soah
Дата 6.7.2009, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  6.7.2009,  08:49 Найти цитируемый пост)
А как насчёт этой строки немного выше 

не заметил

Цитата(djezul @  5.7.2009,  02:35 Найти цитируемый пост)

Код

for ( int i = 0 ; i < N - 1 ; i++ ){            
    if ( i == value ) continue;             
    q[i] = new char[strlen(p[i])+1];    // <- для q[value] память не выделяется
    strcpy( q[i] , p[i] );                            
}



Цитата(djezul @  5.7.2009,  02:35 Найти цитируемый пост)
 
Код

for ( int i = 0 ; i < N ; i++ ){        
    p[i] = new char[strlen(q[i]) + 1];   // <- когда i = value куда указывает q[i]?
    strcpy( p[i] , q[i] );    
}



djezul, 
Цитата(Soah @  5.7.2009,  21:50 Найти цитируемый пост)
надо правильно составлять алгоритмы и пользоваться отладчиком.


PM MAIL   Вверх
djezul
Дата 6.7.2009, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Soah, я уже заменил код на такой 
Код

void Delete(){
    int value;
    stop:
    output();
    cout << "\n\nВведите номмер записи, которую необходимо удалить!\n\n\t>>> ";
    cin >> value;
    value = value - 1;
    if ( value > N - 1 ) {
        system("cls");
        goto stop;
    }
    cout << "\n\n";
    char **q;
    q = new char*[N - 1];
    for ( int i = 0 , k = 0 ; i < N - 1 ; i++ ){
        if ( i != value ){    
            q[k] = new char[strlen(p[i])+1];
            strcpy( q[k] , p[i] );
            k++;
        }
    }
    for ( int i = 0 ; i < N ; i++ )    delete[] p[i];
    delete[] p;
    N = N - 1;
    p = new char*[N];
    for ( int i = 0 ; i < N ; i++ ){
            p[i] = new char[strlen(q[i]) + 1];    
            strcpy( p[i] , q[i] );
    }
    for ( int i = 0 ; i < N ; i++ )    delete[] q[i];
    delete[] q;
}


Цитата(Soah @  6.7.2009,  12:10 Найти цитируемый пост)
надо правильно составлять алгоритмы и пользоваться отладчиком.

Насчёт правильного составления, тут и опыт играет роль, согласитесь . А отладчиком я пользуюсь , и пошаговой отладкой, уже раз 20 прошёл.
Я не понимаю , почему q равно N поидее а не N - 1 . Причём такой момент , если я удаляю последний элемент, всё удаляется, а если не последний , то ошибка в этой строке , p[i] = new char[strlen(q[i]) + 1];    

Цитата(Soah @  6.7.2009,  12:10 Найти цитируемый пост)
// <- когда i = value куда указывает q[i]?

Вот именно , почему возникает вопрос? Ведб в 1 цикле, должно пропускаться . При этом если я делаю так
Код

    for ( int i = 0 ; i < N ; i++ ){
                if ( i != value ){ 
            p[i] = new char[strlen(q[i]) + 1];    
            strcpy( p[i] , q[i] );
                }
    }

То ошибка возникает тут - for ( int i = 0 ; i < N ; i++ )    delete[] q[i];

PM MAIL ICQ Skype   Вверх
Soah
Дата 6.7.2009, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  6.7.2009,  13:00 Найти цитируемый пост)
Вот именно , почему возникает вопрос?

если пока в уме решать такие задачи не получается, возьмите ручку и решайте на бумажке

допустим
p[0] -> "123"
p[1] -> "456"
p[2] -> "789"
p[3] -> "000"

value = 1

Цитата(djezul @  6.7.2009,  13:00 Найти цитируемый пост)

Код

for ( int i = 0 ; i < N - 1 ; i++ ){            
    if ( i == value ) continue;             
    q[i] = new char[strlen(p[i])+1];  
    strcpy( q[i] , p[i] );                            

}


после этого кода
q[0] -> "123"
q[1] -> ???
q[2] -> "789"
как Вы думаете это правильно?


Цитата(djezul @  6.7.2009,  13:00 Найти цитируемый пост)
я уже заменил код на такой 

вроде бы алгоритм правильный, сейчас времени проверить нет, только Вы делаете лишнюю работу
Цитата(djezul @  6.7.2009,  13:00 Найти цитируемый пост)

Код

p = new char*[N];   
for ( int i = 0 ; i < N ; i++ ){           
    p[i] = new char[strlen(q[i]) + 1];                
    strcpy( p[i] , q[i] );    
}    
for ( int i = 0 ; i < N ; i++ )   
    delete[] q[i];    
delete[] q;


зачем создавать копию массива q, если можно присвоить p указатель на ту память которая уже есть
Код

p = q;

PM MAIL   Вверх
djezul
Дата 6.7.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(Soah @  6.7.2009,  13:23 Найти цитируемый пост)
зачем создавать копию массива q, если можно присвоить p указатель на ту память которая уже есть

Да, но если я удалю q , то и p , больше не будет , правильно? А мне нужно , чтобы p остался, правда без удалённого элемента) 
PM MAIL ICQ Skype   Вверх
Soah
Дата 6.7.2009, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  6.7.2009,  13:32 Найти цитируемый пост)
Да, но если я удалю q , то и p , больше не будет , правильно?


а зачем удалять q?

смотрите, 
p ->(указывает) на массив  p[0]..p[3]
p[0] -> "123"
p[1] -> "456"
p[2] -> "789"
p[3] -> "000"

value = 1

формируем q
q[0] -> "123"
q[1] -> "789"
q[2] -> "000"

удаляем память под строки p[0]..p[4] и массив p

p = q, означает что p будет указывать туда где и q, то есть на массив строк("123", "789", "000")

PM MAIL   Вверх
djezul
Дата 6.7.2009, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(Soah @  6.7.2009,  13:45 Найти цитируемый пост)
а зачем удалять q?

Но ведь при 2 вызове функции , разве q сформируется правильно , если не отчистить занимаемою им память?
Ведь возможно у меня будет 
p[0] -> "123"
p[1] -> "456"
p[2] -> "789"
p[3] -> "000"

Я удалю , останется 
q[0] -> "123"
q[1] -> "789"
q[2] -> "000"

Я захочу добавить ещё 2 
q[0] -> "123"
q[1] -> "789"
q[2] -> "000"
q[3] -> "541"
q[4] -> "000"

И снова захочу удалить 5 элемент , но ведб в таком случае , функция правильно не отработает ? Или я что то не так понимаю?
PM MAIL ICQ Skype   Вверх
Soah
Дата 6.7.2009, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 512
Регистрация: 18.2.2009

Репутация: 6
Всего: 54



Цитата(djezul @  6.7.2009,  13:51 Найти цитируемый пост)
функция правильно не отработает ?


Цитата(djezul @  6.7.2009,  13:00 Найти цитируемый пост)

// ...
q = new char*[N - 1];    
for ( int i = 0 , k = 0 ; i < N - 1 ; i++ ){  // <- почему N-1?      
if ( i != value ){ 
// ...

мы ведь перебираем все элементы(N), а не все кроме последнего(N-1) smile 
PM MAIL   Вверх
djezul
Дата 6.7.2009, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 13.6.2009
Где: Украина , Донецк

Репутация: нет
Всего: нет



Цитата(Soah @  6.7.2009,  13:57 Найти цитируемый пост)
мы ведь перебираем все элементы(N), а не все кроме последнего(N-1) smile  

эх.... точно, ведь исправлял эту ошибку, но тогда была ошибка в 1 цикле. Но когда не помогло наверное сделал откат , и эта ошибка снова осталась. Спасибо за помощь.
PM MAIL ICQ Skype   Вверх
ller
Дата 14.7.2009, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

Репутация: 2
Всего: 4



Вопрос по теме. Не буду новую заводить.
Есть некоторый класс
Код

class Matrix
{
private:
    double **matrix;
public:
   Matrix(int x=0,int y=0); // Конструктор выделяет память...
   double operator[][](int i,int j) // Такой оператор как можно сделать?
   ~Matrix();
}


Я понимаю, что так делать нельзя, но есть какие то пути как сделать указание элемента в виде масива n-мерного.

Один из вариантов как я вижу, это использовать
Код

vector<vector<double>> matrix;


Но хочется сделать велосипед, в качестве получения опыта smile

Это сообщение отредактировал(а) ller - 14.7.2009, 21:32
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1122 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.