2014 dxdy logo

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

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




 
 С++. Помогите организовать динамический массив
Сообщение08.04.2011, 22:53 
Здравствуйте! Помогите пожалуйста разобраться с программой.
Задача: создать динамический массив объектов, каждый объект содержит массив слов(до 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 
Ammy в сообщении #432653 писал(а):
1) После выполнения программа выдает критическую ошибку, видимо, жалуясь на деструктор(если не освобождать память, ошибки нет). Что не так?

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

 
 
 
 Re: С++. Помогите организовать динамический массив
Сообщение08.04.2011, 23:35 
nestoklon в сообщении #432658 писал(а):
Уберите квадратные скобки у delete в деструкторе и разберитесь, почему это надо сделать.

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

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

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

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

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

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

 
 
 
 Re: С++. Помогите организовать динамический массив
Сообщение09.04.2011, 00:41 
nestoklon в сообщении #432693 писал(а):
Вот только я не вижу чтобы Вы явно не выходили за границы 20 символов.

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

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

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

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

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

 
 
 [ Сообщений: 6 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group