2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
1

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

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

Author24 — интернет-сервис помощи студентам
Обьясните, почему после второго удаления подмассива происходит ошибка памяти.
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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.11.2013, 08:32
Ответы с готовыми решениями:

Удаление из строки каждое второе вхождение заданной подстроки Pascal
Задание во вложении помогите исправить код!!) Program Stroki; var s1,s2:string; Procedure...

Если второе число равно первому и оба нечетные, то вывести второе число
Написать программу, которая требует ввести первое и второе число оба целые, больше нуля, далее если...

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

Поиск максимального подмассива
Стоит задание: Я набросал код на С++: double FindMaximumSubarray(double arr, unsigned int...

18
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 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
2062 / 618 / 41
Регистрация: 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
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
18.11.2013, 08:53 4
нуль терминатор забыли
1
2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 08:59  [ТС] 5
Croessmah, ок, спасибо, пока кнопку "спасибо" нажимать не буду, чтобы позже вечером, когда буду дома, проверить будет ли так работать или нет, и если работает, то оставлю вам положительный отзыв.
0
Неэпический
17869 / 10634 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
18.11.2013, 09:08 6
Цитата Сообщение от programina Посмотреть сообщение
и если работает, то оставлю вам положительный отзыв
если не одуматся, то оно даже не скомпилируется )
1
programina
18.11.2013, 09:16  [ТС]
  #7

Не по теме:

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

0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
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
2062 / 618 / 41
Регистрация: 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
Модератор
Эксперт С++
13502 / 10754 / 6409
Регистрация: 18.12.2011
Сообщений: 28,700
18.11.2013, 10:28 10
Исправьте только 11 строку на
C++
1
        for ( int i = 0 ; i < N ; i ++ )strcpy(as[ i]," ");
Надо копировать строку, а не указатель.
1
2062 / 618 / 41
Регистрация: 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
4311 / 1422 / 463
Регистрация: 16.12.2010
Сообщений: 2,939
Записей в блоге: 3
18.11.2013, 11:10 12
programina, таких недоразумений можно избежать, навсегда запомнив правило, что строковые литералы не нужно изменять, поэтому всегда предварять const. Ошибка будет на этапе компиляции, а не выполнения.
В данном случае mingw, например, выдает варнинг conversion from string constant to 'char*'.
1
2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
18.11.2013, 11:19  [ТС] 13
BumerangSP, так?
C++
void add ( int id, const char * s )
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
18.11.2013, 11:36 14
Цитата Сообщение от BumerangSP Посмотреть сообщение
навсегда запомнив правило, что строковые литералы не нужно изменять,
И чему это поможет? Написать
C++
1
as[i]=(char *)s;
? Когда не понимаешь смысла своих действий, константность уже не поможет.
1
4311 / 1422 / 463
Регистрация: 16.12.2010
Сообщений: 2,939
Записей в блоге: 3
18.11.2013, 11:40 15
programina, угу.
taras atavin, если мы уже добавили const, то предполагается, что мы уже знаем, что так делать нельзя.)
1
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
18.11.2013, 11:50 16
Цитата Сообщение от BumerangSP Посмотреть сообщение
taras atavin, если мы уже добавили const, то предполагается, что мы уже знаем, что так делать нельзя.)
Разве? Да и такого знания хватает только на то, чтоб считать чужие ошибки на двойку, или стирать ересь. Для того, чтоб писать своё, надо знать, как надо, а не как нельзя. Если только не пишешь наглядное пособие, как делать не надо.
0
BumerangSP
18.11.2013, 12:41
  #17

Не по теме:

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

0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
18.11.2013, 13:11 18
Оно конечно так, но так просто от ошибок не избавишься. Даже конкретно эта ошибка алгоритмическая и синтаксическими средствами её можно только прикрыть "туманом".
0
SatanaXIII
18.11.2013, 14:18     Второе удаление подмассива
  #19
 Комментарий модератора 
Завязываем.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.11.2013, 14:18

Поиск подмассива в массиве
Найти последнее вхождение подмассива в массиве Массив заполнить случайными числами, размеры...

Программа возвращения подмассива.
Здравствуйте!Тут проблемка..надо написать программу, с помощью цикла &quot;for&quot;, возвращающую подмассив...

Поиск подмассива в массиве
Если подмассив найден в массиве, то вернуть нужно минимальный индекс, с которого начинается...

Переворот подмассива 2 раза
Задан массив из n чисел (a1, a2,..., an). На нем два раза осуществляют операцию переворота...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru