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

Null pointer assignment. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.78
Stalin45
2 / 2 / 0
Регистрация: 24.04.2011
Сообщений: 66
24.08.2011, 00:20     Null pointer assignment. #1
Здравствуйте. Такая проблема: Пытаюсь вызвать функция класса Up()
s2 = s1.up(), возвращая указатель на строку (по-умолчанию в s2 пустая строка имеет адрес NULL).
Вот только почему передается не ссылка, а само значение строки, поскольку компилятор пишет: null pointer assignment. Значит ссылка не поменялась, и он, не выделив память, прострочил прямо с нулевого адреса...
И второй вопрос, как можно в данном случае все-таки передать значение (хотя первый вопрос в силе), но так, чтобы выделить точное кол-во памяти под передаваемую строку в s2?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "iostream.h"
#include "CONIO.h"
#include "Ctype.h"
#include "string.h"
using namespace std;
class String
{
 private:
  char* st;
 public:
  String(): st(NULL) {}
  String(char* str) {int len = strlen(str);
             st = new char[len+1]; strcpy(st, str);
            }
  ~String() {delete st;}
  void show()const {cout<<endl<<st;}
  String up() {int len = strlen(st);
           for(int i=0; i<len; i++) st[i] = toupper(st[i]); return st;
          }
};
///////////////////
int main()
{
 String s1 = "Test yes TEsT";
 String s2;
 s2 = s1.up();
 s2.show();
 getch();
return 0;
}
Заранее благодарен!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.08.2011, 00:20     Null pointer assignment.
Посмотрите здесь:

C++ Null pointer assignment
Ошибка Null pointer assignment C++
C++ Не работает код: m_web1.Navigate ('gidro.htm',0,0,NULL,NULL);
string, invalid null pointer C++
delete[] *pointer vs. delete pointer и утечка памяти C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Stalin45
2 / 2 / 0
Регистрация: 24.04.2011
Сообщений: 66
25.08.2011, 02:08  [ТС]     Null pointer assignment. #21
Благодарю за глубокие объяснения. Изучил механизмы конструктора копирования и перегрузки присваивания. Остались 2 вопроса:

1). Я правильно понял, конструктор копирования запускается в момент инициализации только что созданного объекта, а перегруженная операция присваивания во всех остальных случаях присваивания?
2). В строках:
C++
1
2
3
4
5
String operator= (const String& s1) {int len = strlen(s1.st);
                                       st = new char[len+1];
                                       strcpy(st, s1.st);
                                       return String(st);
                                      }
Для чего вообще возвращать куда-то (не пойму, куда) значение, если я итак уже сделал все, что нужно в строке:
C++
1
 strcpy(st, s1.st);
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
25.08.2011, 02:22     Null pointer assignment. #22
Цитата Сообщение от Stalin45 Посмотреть сообщение
Благодарю за глубокие объяснения. Изучил механизмы конструктора копирования и перегрузки присваивания. Остались 2 вопроса:

1). Я правильно понял, конструктор копирования запускается в момент инициализации только что созданного объекта, а перегруженная операция присваивания во всех остальных случаях присваивания?
Да.

Цитата Сообщение от Stalin45 Посмотреть сообщение
Для чего вообще возвращать куда-то (не пойму, куда) значение, если я итак уже сделал все, что нужно в строке:
C++
1
 strcpy(st, s1.st);
Опреатор= возвращает значение, чтобы можно было использовать его в цепочке присваиваний (или как часть выражения):
C++
1
a = b = c;
Причём для обычных типов можно (хотя и бессмысленно) записать так:
C++
1
(a = b) = c;
Для того, чтобы эта возможность сохранилась и для перегруженного оператора, он должен возвращать ссылку на объект, а не просто значение.
Сыроежка
Заблокирован
25.08.2011, 19:28     Null pointer assignment. #23
Цитата Сообщение от Stalin45 Посмотреть сообщение
Благодарю за глубокие объяснения. Изучил механизмы конструктора копирования и перегрузки присваивания. Остались 2 вопроса:

1). Я правильно понял, конструктор копирования запускается в момент инициализации только что созданного объекта, а перегруженная операция присваивания во всех остальных случаях присваивания?
2). В строках:
C++
1
2
3
4
5
String operator= (const String& s1) {int len = strlen(s1.st);
                                       st = new char[len+1];
                                       strcpy(st, s1.st);
                                       return String(st);
                                      }
Для чего вообще возвращать куда-то (не пойму, куда) значение, если я итак уже сделал все, что нужно в строке:
C++
1
 strcpy(st, s1.st);
У вас неправильно написан оператор присваивания. Вы заабыли удалить память, на которую указывает указатель st того объекта, которому вы присваиваете новое значение.

Что касается конструктора копирования, то он также используется, когда вы передаете объекты в качестве аргументов функций, и при возвращении из функций объектов вашего класса.

 Комментарий модератора 
Убедительная просьба - заканчивайте постоянный оверквотинг. Нет никакого смысла каждый раз цитировать сообщение целиком, лучше сделать несколько цитат, но цитировать существенные места, которые вы комментируете.
Stalin45
2 / 2 / 0
Регистрация: 24.04.2011
Сообщений: 66
25.08.2011, 23:13  [ТС]     Null pointer assignment. #24
Цитата Сообщение от Сыроежка Посмотреть сообщение
Вы заабыли удалить память, на которую указывает указатель st того объекта, которому вы присваиваете новое значение.
Простите, но я не понял, вы не могли бы подробнее?
Вот как я это вижу:
Оператор в качестве аргумента получает ссылку....следовательно вы точно говорите не про объект-аргумент (его удалять не надо). Я выделяю память под st объекта-получателя. Возвращает оператор временный объект, из которого при необходимости копируются данные, после чего он удаляется...так что нужно удалять вручную???
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
25.08.2011, 23:23     Null pointer assignment. #25
Stalin45, поскольку оператор присваивания работает с уже созданным объектом-получателем, то возможно получатель уже содержит в себе некоторую строку, на которую указывает его st. Когда выделяется память под новое содержимое, указатель на эту память записывается в st, а та область памяти, на которую раньше указывал st оказывается потерянной. Поэтому перед выделением памяти старую надо освободить. А чтобы случайно при этом не удалить источник, надо бы проверить, не присваиваем ли мы самого себе.
Кстати, в некоторых случаях может оказаться приемлемым не выделять лишний раз память. Для этого можно хранить размер выделенного буфера, и если он не меньше размера копируемой строки, то просто копировать поверх старого содержимого, без удаления/выделения. Но в некоторых случаях такое поведение не желательно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.08.2011, 00:22     Null pointer assignment.
Еще ссылки по теме:

C++ Null pointer
C++ Из-за чего может возникать следующая ошибка: "Invalid null pointer"?
Error null pointer assignment C++

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

Или воспользуйтесь поиском по форуму:
Stalin45
2 / 2 / 0
Регистрация: 24.04.2011
Сообщений: 66
26.08.2011, 00:22  [ТС]     Null pointer assignment. #26
Спасибо! Тогда, чтобы подытожить, вот финальная версия оператора присваивания.
C++
1
2
3
4
5
6
7
8
String& operator= (const String& s1) { if (this == &s1) return *this;
                 
                                       delete [] st;
                                       int len = strlen(s1.st);
                                       st = new char[len+1];
                                       strcpy(st, s1.st);
                                       return *this;
                                     }
Yandex
Объявления
26.08.2011, 00:22     Null pointer assignment.
Ответ Создать тему
Опции темы

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