С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
#1

Второе удаление подмассива - C++

18.11.2013, 08:32. Просмотров 446. Ответов 18
Метки нет (Все метки)

Обьясните, почему после второго удаления подмассива происходит ошибка памяти.
C++
struct massiv
{
  massiv()
  {
    as = new char*[N];
    for(int i = 0; i < N; i++) as[i] = new char[2];
    for(int i = 0; i < N; i++) as[i][0] = " ";
  }
 
  void add(int id, char* s)
  {
    delete [] as[id];
    int sz = strlen(s);
    as[id] = new char[sz];
    as[id] = s;
  }
};
 
int main()
{
  massiv my;
  
  my.add(0, "Hello, "); // ok
  my.add(1, "world");  // ok
  my.add(1, "people"); // bad allocation
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2013, 08:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Второе удаление подмассива (C++):

Выделение подмассива - C++
Сегодня начал разбирать свою лекицию по Си, и застрял на этом фрагменте, который выделяет подмассив. Компилятор подсвечивает что...

Путем перестановок строк и столбцов элемент переместить в правый верхний угол подмассива (С Turbo Pascal на C++) - C++
Можете программу преобразовать в C++?? Задан двумерный массив N x N. Последовательно рассматриваются квадратные подмассивы, правый...

Путем перестановок строк и столбцов (целиком) элемент надо переместить в правый верхний угол подмассива (Перевести программу в c++) - C++
program zadanie_5; uses crt; const nn=5; var i, j, imax, jmax, n, k, m: integer; a: array of real; r: real;...

Второе ядро - C++
Как задействовать второе ядро? Что бы оно тоже принимало участие в обработке данных

Здесь есть удаление столбца, как добавить удаление строки - C++
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int main() { int n; do {cout &lt;&lt; &quot;Razmer massiva: &quot;; cin &gt;&gt; n;...

Описать класс «множество» (добавление и удаление элемента, пересечение, объединение и удаление множеств ) - C++
Описать класс «множество», позволяющий выполнять основные операции – добавление и удаление элемента, пересечение, объединение и удаление...

18
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
18.11.2013, 08:41 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
2
    as[id] = new char[sz];
    as[id] = s;//Копирование указателя
Вы копируете указатель, а не символы, значит в результате освобождаете строковый литерал

Добавлено через 1 минуту
C++
1
as[i][0] = " ";
char* в char?
1
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 08:49  [ТС] #3
Croessmah, а так нормально?
C++
for(int i = 0; i < sz; i++)
  as[id][i] = s[i];
зы: сейчас не могу проверить на компе.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
18.11.2013, 08:53 #4
нуль терминатор забыли
1
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 08:59  [ТС] #5
Croessmah, ок, спасибо, пока кнопку "спасибо" нажимать не буду, чтобы позже вечером, когда буду дома, проверить будет ли так работать или нет, и если работает, то оставлю вам положительный отзыв.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
18.11.2013, 09:08 #6
Цитата Сообщение от programina Посмотреть сообщение
и если работает, то оставлю вам положительный отзыв
если не одуматся, то оно даже не скомпилируется )
1
programina
18.11.2013, 09:16  [ТС]
  #7

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
если не одуматся, то оно даже не скомпилируется )
без паники, я лично контролирую ситуацию, поэтому все скомпилируется

0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.11.2013, 09:30 #8
C++
1
2
3
4
5
6
7
void add(int id, char* s)
{
 delete [] as[id];
 int sz = strlen(s);
 as[id] = new char[sz]; // Здесь выделяется память оператором new
 as[id] = s; // А здесь указателю as[id] присваивается значение параметра s, равное адресу переданной в метод нуль-терминальной строки, которая может находиться в защищённой памяти. При этом адрес памяти, выделенной предыдущей строкой теряется. При следующем delete [] as[id]; будет предпринята попытка освободить память, адрес которой хранится в as[id].
}
1
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 10:05  [ТС] #9
Проверьте вывод программы, пожалуйста.
C++
#include <cstdio>
#include <cstring>
#define N 100
 
struct massiv
{
    massiv ()
    {
        as = new char *[ N ] ;
        for ( int i = 0 ; i < N ; i ++ ) as [ i] = new char [2 ] ;
        for ( int i = 0 ; i < N ; i ++ ) as [ i] = " " ;
    }
 
    char **as;
 
    void add ( int id, char * s )
    {
        delete [] as [ id] ;
        int sz = strlen ( s) ;
        as[id] = new char[ sz+1] ;
        for(int i = 0; i < sz; i ++)
            as [ id][i] = s[i];
        as[id][sz] = '\0';
    }
 
    char *get(int id)
    {
        return as[id];
    }
} ;
 
int main ()
{
    massiv my;
 
    my. add (0 , "Hello, " ) ;
    my. add (1 , "world" ) ;
 
    printf( "%s", my.get(0) );
    printf( "%s\n", my.get(1) );
 
    my.add(1, "people");
 
    printf( "%s", my.get(0) );
    printf( "%s\n", my.get(1) );
}
0
zss
Модератор
Эксперт С++
6587 / 6149 / 2025
Регистрация: 18.12.2011
Сообщений: 16,034
Завершенные тесты: 1
18.11.2013, 10:28 #10
Исправьте только 11 строку на
C++
1
        for ( int i = 0 ; i < N ; i ++ )strcpy(as[ i]," ");
Надо копировать строку, а не указатель.
1
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 11:08  [ТС] #11
Цитата Сообщение от zss Посмотреть сообщение
Исправьте только 11 строку на
C++
1
        for ( int i = 0 ; i < N ; i ++ )strcpy(as[ i]," ");
Надо копировать строку, а не указатель.
точно! Здесь тоже надо.

Добавлено через 7 минут
Сейчас все работает. Всем спасибо.

Добавлено через 9 минут
Croessmah, форум пока не разрешает добавить вам отзыв, добавлю позже.

Добавлено через 16 минут
C++
#include <cstdio>
#include <cstring>
#define N 100
 
struct massiv
{
  massiv ()
  {
    as = new char *[N] ;
    for ( int i = 0 ; i < N ; i++ ) as[i] = new char[2] ;
    for ( int i = 0 ; i < N ; i++ ) //strcpy( as[i], "-" ) ;
    {
      as[i][0] = '-';
      as[i][1] = '\0';
    }
  }
 
  char **as;
 
  void add ( int id, char * s )
  {
    delete [] as [id] ;
    int sz = strlen (s) ;
    as[id] = new char[sz+1] ;
    for(int i = 0; i < sz; i ++) as[id][i] = s[i];
    as[id][sz] = '\0';
  }
 
  char *get(int id)
  {
    return as[id];
  }
} ;
 
int main ()
{
  massiv my ;
 
  my.add(2 , "Hello, ") ;
  my.add(3 , "world") ;
  my.add(4, "?");
 
  for(int i = 0; i < 7; i++) printf( "%s", my.get(i) );
  printf("\n");
 
  my.add(3, "people");
  my.add(4, "!");
 
  for(int i = 0; i < 7; i++) printf( "%s", my.get(i) );
  printf("\n");
}
Bash
--Hello, world?--
--Hello, people!--
0
BumerangSP
4287 / 1409 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
18.11.2013, 11:10 #12
programina, таких недоразумений можно избежать, навсегда запомнив правило, что строковые литералы не нужно изменять, поэтому всегда предварять const. Ошибка будет на этапе компиляции, а не выполнения.
В данном случае mingw, например, выдает варнинг conversion from string constant to 'char*'.
1
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 11:19  [ТС] #13
BumerangSP, так?
C++
void add ( int id, const char * s )
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.11.2013, 11:36 #14
Цитата Сообщение от BumerangSP Посмотреть сообщение
навсегда запомнив правило, что строковые литералы не нужно изменять,
И чему это поможет? Написать
C++
1
as[i]=(char *)s;
? Когда не понимаешь смысла своих действий, константность уже не поможет.
1
BumerangSP
4287 / 1409 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
18.11.2013, 11:40 #15
programina, угу.
taras atavin, если мы уже добавили const, то предполагается, что мы уже знаем, что так делать нельзя.)
1
18.11.2013, 11:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2013, 11:40
Привет! Вот еще темы с ответами:

Изъять из строки второе предложение - C++
Прошу помощи с заданием, буду очень благодарен. Задание следующее: Изъять из строки(задается пользователем в процессе выполнения...

Есть ли второе вхождение в строке - C++
Как найти есть ли второе вхождение в строке? int pos = str1.find(str2); Дело в том что str2 это уже строчка взята из этой строки (str1)...

Определить второе по величине число - C++
Даны 3 числа, определить второе по величине число. Какая у у меня ошибка? int a, b, c; cin &gt;&gt; a &gt;&gt; b &gt;&gt; c; if ((b &gt; a &gt;...

Как зделать второе уровнение? - C++
http://s018.***********/i515/1405/2c/240cb2131d37.jpg


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.