Модераторы: 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   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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