Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 08:32     Второе удаление подмассива #1
Обьясните, почему после второго удаления подмассива происходит ошибка памяти.
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
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2013, 08:32     Второе удаление подмассива
Посмотрите здесь:

Второе ядро C++
Путем перестановок строк и столбцов (целиком) элемент надо переместить в правый верхний угол подмассива (Перевести программу в c++) C++
Выделение подмассива C++
C++ Путем перестановок строк и столбцов элемент переместить в правый верхний угол подмассива (С Turbo Pascal на C++)
C++ Описать класс «множество» (добавление и удаление элемента, пересечение, объединение и удаление множеств )
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 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?
programina
 Аватар для programina
1912 / 597 / 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];
зы: сейчас не могу проверить на компе.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
18.11.2013, 08:53     Второе удаление подмассива #4
нуль терминатор забыли
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 08:59  [ТС]     Второе удаление подмассива #5
Croessmah, ок, спасибо, пока кнопку "спасибо" нажимать не буду, чтобы позже вечером, когда буду дома, проверить будет ли так работать или нет, и если работает, то оставлю вам положительный отзыв.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,915
Записей в блоге: 2
Завершенные тесты: 1
18.11.2013, 09:08     Второе удаление подмассива #6
Цитата Сообщение от programina Посмотреть сообщение
и если работает, то оставлю вам положительный отзыв
если не одуматся, то оно даже не скомпилируется )
programina
18.11.2013, 09:16  [ТС]
  #7

Не по теме:

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

taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
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].
}
programina
 Аватар для programina
1912 / 597 / 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) );
}
zss
Модератор
Эксперт С++
 Аватар для zss
5950 / 5555 / 1787
Регистрация: 18.12.2011
Сообщений: 14,197
Завершенные тесты: 1
18.11.2013, 10:28     Второе удаление подмассива #10
Исправьте только 11 строку на
C++
1
        for ( int i = 0 ; i < N ; i ++ )strcpy(as[ i]," ");
Надо копировать строку, а не указатель.
programina
 Аватар для programina
1912 / 597 / 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!--
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
18.11.2013, 11:10     Второе удаление подмассива #12
programina, таких недоразумений можно избежать, навсегда запомнив правило, что строковые литералы не нужно изменять, поэтому всегда предварять const. Ошибка будет на этапе компиляции, а не выполнения.
В данном случае mingw, например, выдает варнинг conversion from string constant to 'char*'.
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 11:19  [ТС]     Второе удаление подмассива #13
BumerangSP, так?
C++
void add ( int id, const char * s )
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.11.2013, 11:36     Второе удаление подмассива #14
Цитата Сообщение от BumerangSP Посмотреть сообщение
навсегда запомнив правило, что строковые литералы не нужно изменять,
И чему это поможет? Написать
C++
1
as[i]=(char *)s;
? Когда не понимаешь смысла своих действий, константность уже не поможет.
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
18.11.2013, 11:40     Второе удаление подмассива #15
programina, угу.
taras atavin, если мы уже добавили const, то предполагается, что мы уже знаем, что так делать нельзя.)
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.11.2013, 11:50     Второе удаление подмассива #16
Цитата Сообщение от BumerangSP Посмотреть сообщение
taras atavin, если мы уже добавили const, то предполагается, что мы уже знаем, что так делать нельзя.)
Разве? Да и такого знания хватает только на то, чтоб считать чужие ошибки на двойку, или стирать ересь. Для того, чтоб писать своё, надо знать, как надо, а не как нельзя. Если только не пишешь наглядное пособие, как делать не надо.
BumerangSP
18.11.2013, 12:41
  #17

Не по теме:

taras atavin, понятное дело, нужно знать, что пишешь. Только здесь играет роль и человеческий фактор. Ошибаться свойственно всем людям.

taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.11.2013, 13:11     Второе удаление подмассива #18
Оно конечно так, но так просто от ошибок не избавишься. Даже конкретно эта ошибка алгоритмическая и синтаксическими средствами её можно только прикрыть "туманом".
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2013, 14:18     Второе удаление подмассива
Еще ссылки по теме:

Здесь есть удаление столбца, как добавить удаление строки C++
C++ Найти в массиве второе по величине число
C++ Как зделать второе уровнение?

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

Или воспользуйтесь поиском по форуму:
SatanaXIII
18.11.2013, 14:18     Второе удаление подмассива
  #19
 Комментарий модератора 
Завязываем.
Yandex
Объявления
18.11.2013, 14:18     Второе удаление подмассива
Ответ Создать тему
Опции темы

Текущее время: 17:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru