2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 С++. Помогите организовать динамический массив
Сообщение08.04.2011, 22:53 


08/04/11
3
Здравствуйте! Помогите пожалуйста разобраться с программой.
Задача: создать динамический массив объектов, каждый объект содержит массив слов(до 10) и их количество, а так же умеет считать количество слов, начинающихся с англ буквы "а". Программа, создающая 1 объект:
Заголовочный файл TS.h
код: (TS.h) [ скачать ] [ спрятать ]
Используется синтаксис C++
class TS
{
private:  int n;
                char *words[10];
public:
                TS(char *sentence);
                ~TS(void){int i;
                        for (i=0;i<n;i++)
                        delete [] words[i];}
                int vowel(void);
};

Файл TS.cpp
код: (TS.cpp) [ скачать ] [ спрятать ]
Используется синтаксис C++
#include "StdAfx.h"
#include "TS.h"
#include <string.h>
#include <stdlib.h>
TS::TS(char *sentence)
{char *ptr1; int i(0);
        ptr1=strchr(sentence,' ');
        while (ptr1!=NULL) { // отделение 1го слова
                words[i]=new char[20];
                *words[i]='\0';
                strncpy(words[i],sentence,ptr1-sentence);
                sentence=ptr1+1;
                ptr1=strchr(sentence,' ');
                i++;
        }
        words[i]=new char[20];
        strcpy(words[i],sentence);//остаток строки - последнее слово
        n=i+1;
};
int TS::vowel(void)
{int i,k(0);
        for (i=0;i<n;i++)
                if (*words[i]=='a') k++;
        return k;
}

Основная программа
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include "stdafx.h"
#include "TS.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{char *str;
        str=new char[200];
        gets(str);
        TS pr1(str);
        cout<<pr1.vowel()<<'\n';
        pr1.~TS();
        _getch();
        return 0;
}


1) После выполнения программа выдает критическую ошибку, видимо, жалуясь на деструктор(если не освобождать память, ошибки нет). Что не так?
2) Надо динамический массив => использовать вектора. Из того, что удалось прочитать в интернете, я поняла, что это, но не вполне поняла, как это записать в программе(не удается в вектор положить объект), т.к. большинство примеров не на классы. Объясните пожалуйста, как это сделать и, если можно, дайте ссылку на учебник с хорошими примерами

 Профиль  
                  
 
 
Сообщение08.04.2011, 23:02 
Заслуженный участник


19/07/08
1266
Ammy в сообщении #432653 писал(а):
1) После выполнения программа выдает критическую ошибку, видимо, жалуясь на деструктор(если не освобождать память, ошибки нет). Что не так?

В классе TS
1) Уберите квадратные скобки у delete в деструкторе и разберитесь, почему это надо сделать.
2) Если $n$ равно 10 не всегда, то что там в деструкторе в цикле удаляется?
Дальше не читал.

 Профиль  
                  
 
 Re: С++. Помогите организовать динамический массив
Сообщение08.04.2011, 23:35 


08/04/11
3
nestoklon в сообщении #432658 писал(а):
Уберите квадратные скобки у delete в деструкторе и разберитесь, почему это надо сделать.

Память, выделенная new [] освобождается с помощью delete [], т.к. иначе освобождается память указателя на 1й элемент, а остальные элементы остаются, просто мы теряем к ним доступ. Разве не так?

nestoklon в сообщении #432658 писал(а):
2) Если $n$ равно 10 не всегда, то что там в деструкторе в цикле удаляется?

words - указатели на слова; если слова есть, то под них была выделена память и ее надо освободить, если нет, то освобождать нечего, поэтому в цикле удаляются слова по энный, а остальных просто не было...

 Профиль  
                  
 
 Re: С++. Помогите организовать динамический массив
Сообщение09.04.2011, 00:13 
Заслуженный участник


19/07/08
1266
Ammy в сообщении #432677 писал(а):
Память, выделенная new [] освобождается с помощью delete [], т.к. иначе освобождается память указателя на 1й элемент, а остальные элементы остаются, просто мы теряем к ним доступ. Разве не так?
О! И правда. Хорошо, уговорили. Зря дальше не читал. Вот только я не вижу чтобы Вы явно не выходили за границы 20 символов.
Ammy в сообщении #432677 писал(а):
указатели на слова; если слова есть, то под них была выделена память и ее надо освободить, если нет, то освобождать нечего, поэтому в цикле удаляются слова по энный, а остальных просто не было...
А если их больше 10, то что?

И в целом, я честно говоря не помню, вообще деструктор явно вызывать можно или нет. Но то, что его явно вызывать совершенно не за чем -- это точно. У Вас объявлена переменная, у которой область действия кончается при окончании программы. Казалось бы, тут-то деструктор и должен сработать. А он уже был вызван. Явно. Вставьте какой-нибудь вывод в деструктор чтобы понять -- не вызывается ли он часом два раза?

UPD Проверил. Таки вызывается. Два раза. Ещё про ошибки рассказывать?

 Профиль  
                  
 
 Re: С++. Помогите организовать динамический массив
Сообщение09.04.2011, 00:41 


08/04/11
3
nestoklon в сообщении #432693 писал(а):
Вот только я не вижу чтобы Вы явно не выходили за границы 20 символов.

А если их больше 10, то что?

Обработку крайних случаев и ошибок я оставила напоследок, что бы не загромождать код
nestoklon в сообщении #432693 писал(а):
Но то, что его явно вызывать совершенно не за чем -- это точно. У Вас объявлена переменная, у которой область действия кончается при окончании программы. Казалось бы, тут-то деструктор и должен сработать. А он уже был вызван.

Спасибо большое, мне такая мысль в голову и не пришла :roll:
nestoklon в сообщении #432693 писал(а):
Ещё про ошибки рассказывать?

Любые замечания выслушаю с удовольствием)

 Профиль  
                  
 
 Re: С++. Помогите организовать динамический массив
Сообщение09.04.2011, 01:17 
Заслуженный участник


19/07/08
1266
Ammy в сообщении #432702 писал(а):
Любые замечания выслушаю с удовольствием)
1) Вам не нужны все эти заголовочные файлы. Первый из них вообще непонятно что и зачем. Пока не убрал, не компилировалось.
2) Признаюсь, меня запутал ваш вектор указателей, каждый их которых выделяется как динамический массив. Как-то оно странно. В C++ есть строки. Которые ведут себя как строки. Почему их не использовать?
3) В продолжение прошлому замечанию. Приведённый код -- достаточно странное сочетание c и c++. Как правило, лучше определиться и следовать стилистике одного из языков.
Можно конкретнее, но как ни пытался указать на конкретную проблему, она сводилась к тому что мешается c и c++. То есть, вроде всё правильно, но так лучше не делать.
Ну вот, например. gets и cout. Уж или gets+puts или cin+cout. Не говоря о том, что
Википедия писал(а):
Многие источники советуют программистам никогда не использовать gets в новых программах.
Применение gets весьма осуждается. Функция оставлена в стандартах C89 и C99 для обратной совместимости. Множество инструментов разработки ПО, как например, GNU ld выдает предупреждения в случае обнаружения при компоновке кода с использованием gets.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group