Форум программистов, компьютерный форум 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++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
24.08.2011, 00:46     Null pointer assignment. #2
Проблема вот в чём.
В строке 26 функция up() создаёт временный объект String (из указателя). Дальше этот временный объект используется для создания s2 с помощью конструктора копирования. Затем временный объект уничтожается.
А теперь сама проблема: конструктор копирования, созданный компилятором, копирует только указатель, но не само содержимое строки. После удаления временного объекта копия указателя в новом объекте указывает на уже удалённую область памяти.
Выход: определить свой конструктор копирования, который будет осуществлять "глубокое копирование", то есть скопирует не указатель, а саму строку.

Добавлено через 15 минут
Цитата Сообщение от Stalin45 Посмотреть сообщение
возвращая указатель на строку
Цитата Сообщение от Stalin45 Посмотреть сообщение
Вот только почему передается не ссылка, а само значение строки
Ну во-первых всё-таки указатель, а не ссылку.
Во вторых, функция объявлена как возвращающая String, поэтому создаётся временный оъект. А поскольку конструктор объявлен без explicit, то осуществляется неявное преобразование из указателя.
Проблема должна уйти, если объявить функцию up() как возвращающую указатель, но тем не менее конструктор копирования для такого класса в любом случае нужен.

Добавлено через 2 минуты
И ещё, в конструктор было бы правильнее принимать указатель на константную строку, то есть
C++
1
String(const char* str)
или
C++
1
String(char const* str)
что одно и то же.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.08.2011, 02:33     Null pointer assignment. #3
Класс, в котором конструктор динамически запрашивает память, обязан реализовать: конструктор копирования, деструктор, операцию присваивания. Остальное - по необходимости.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
24.08.2011, 08:12     Null pointer assignment. #4
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
обязан реализовать
Либо запретить их использование помещением их определения в private.
Stalin45
2 / 2 / 0
Регистрация: 24.04.2011
Сообщений: 66
24.08.2011, 13:34  [ТС]     Null pointer assignment. #5
grizlik78, огромное спасибо за разъяснение механизма возврата (я считал, что функция up() возвращает объект объект String, через который и запускалась функция изначально, а не создает временный и недолговечный. Это многое объясняет!).

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Класс, в котором конструктор динамически запрашивает память, обязан реализовать: конструктор копирования, деструктор, операцию присваивания. Остальное - по необходимости.
Операция присваивания...если я правильно понял, то это перегрузка operator= (никогда раньше не использовал).
Попробовал динамически выделить память:
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);
                      }
Как всегда все работает, однако в конце все ещё надпись: Null poinet assignment.
Но ведь на этот раз память выделена! Быть может эта надпись появляется даже когда просто NULL адрес был присвоен, но значение в нем не изменено?
C++
1
  String(): st(NULL)
C++
1
2
3
 String s2;
 s2 = s1;
 s2.show();
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
24.08.2011, 13:40     Null pointer assignment. #6
Цитата Сообщение от Stalin45 Посмотреть сообщение
однако в конце все ещё надпись: Null poinet assignment.
Так и ошибка никуда не делась.)
Возвращать нужно не String, а String&
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
24.08.2011, 13:40     Null pointer assignment. #7
Stalin45, Сигнатура оператора неверная.

C++
1
String& operator= (const String& s1);
Stalin45
2 / 2 / 0
Регистрация: 24.04.2011
Сообщений: 66
24.08.2011, 13:45  [ТС]     Null pointer assignment. #8
Вот я дурак, я же не указатели на String присваиваю друг другу, а обычные объекты!! Т.е. моя функция operator= (String* s1) даже не вызывалась...
Получилось решить проблему строкой:
C++
1
 s2 = &s1
но, верно, в данном случае удобнее изменить сам operator=
Спасибо!
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
24.08.2011, 13:45     Null pointer assignment. #9
Кстати да, я почему-то рассказал про конструктор копирования, хотя в данном случае используется операция присваивания. Ну да не суть, они оба должны быть определены.
И помимо неправильной сигнатуры есть ещё маленькая деталь — в операторе присваивания стоит проверять на присваивание самому себе (это в данном случае не важно, но всё-таки), а ещё перед присваиванием удалять старое содержимое.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.08.2011, 13:50     Null pointer assignment. #10
Герб Саттер приводит много более элегантную реализацию операции присваивания:
C++
1
2
3
4
5
6
Листинг 3.12. Реализация операции присваивания "по Саттеру"
TArray& TArray::operator=(const TArray &t)
{ TArray temp(t);       // временнный локальный объект temp = t
  Swap(temp);           // обмен полями с текущим объектом
  return *this;             // возврат текущего объекта
}                   // temp уничтожен
Swap - это функция обмена. Часто можно использовать std::swap().
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
24.08.2011, 15:11     Null pointer assignment. #11
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
много более элегантную реализацию операции присваивания
Причём, устраняющую проблему самоприсваивания.
Но там ещё есть условие, что Swap должна быть бессбойной.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.08.2011, 15:24     Null pointer assignment. #12
Цитата Сообщение от Deviaphan Посмотреть сообщение
Причём, устраняющую проблему самоприсваивания.
Но там ещё есть условие, что Swap должна быть бессбойной.
Да. И стандартная swap этому удовлетворяет.
Поэтому я практически всегда стараюсь использовать вариант Саттера - писать меньше...
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
24.08.2011, 15:26     Null pointer assignment. #13
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
И стандартная swap этому удовлетворяет.
Не удовлетворяет. Если у объекта нет бессбойного конструктора копирования и деструктора, то не удовлетворяет.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.08.2011, 16:05     Null pointer assignment. #14
Цитата Сообщение от Deviaphan Посмотреть сообщение
Не удовлетворяет. Если у объекта нет бессбойного конструктора копирования и деструктора, то не удовлетворяет.
Спасибо за напоминание...
Сыроежка
Заблокирован
24.08.2011, 21:22     Null pointer assignment. #15
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Герб Саттер приводит много более элегантную реализацию операции присваивания:
C++
1
2
3
4
5
6
Листинг 3.12. Реализация операции присваивания "по Саттеру"
TArray& TArray::operator=(const TArray &t)
{ TArray temp(t);       // временнный локальный объект temp = t
  Swap(temp);           // обмен полями с текущим объектом
  return *this;             // возврат текущего объекта
}                   // temp уничтожен
Swap - это функция обмена. Часто можно использовать std::swap().
Нельзя использовать std::swap, так как в вашем примере используется синтаксис для вызова функции swap - члена класса.

Добавлено через 7 минут
Цитата Сообщение от Stalin45 Посмотреть сообщение
Здравствуйте. Такая проблема: Пытаюсь вызвать функция класса 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;
}
Заранее благодарен!
У вас тут несколько ошибок. первое - у вас не определен конструктор копирования. Второе - у вас нет определения оператора присваивания. Третье - в деструкторе вы вместо delete выражения должны использовать delete [] выражение, так как вы должны удалить массив. Четвертое - в функции up вы не делаете проверку на то, что ваш указатель равен NULL.

Саму функцию up можно написать проще.

C++
1
2
3
4
5
6
7
8
9
String String::up() const
{
   if ( st )
   {
      while ( *st ) *st = toupper( *st );
   }
 
   return ( st );
}
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
24.08.2011, 21:26     Null pointer assignment. #16
Цитата Сообщение от Сыроежка Посмотреть сообщение
while ( *st ) *st = toupper( *st );
infinite loop detected.
Сыроежка
Заблокирован
24.08.2011, 21:29     Null pointer assignment. #17
Цитата Сообщение от grizlik78 Посмотреть сообщение
infinite loop detected.
И как вы определили infinite loop, не подскажите?
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
24.08.2011, 21:30     Null pointer assignment. #18
Глазами. Где переход к следующему символу?
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.08.2011, 21:31     Null pointer assignment. #19
Цитата Сообщение от Сыроежка Посмотреть сообщение
И как вы определили infinite loop, не подскажите?
Элементарно, Ватсон!... указатель не изменяется...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.08.2011, 21:33     Null pointer assignment.
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Сыроежка
Заблокирован
24.08.2011, 21:33     Null pointer assignment. #20
Цитата Сообщение от grizlik78 Посмотреть сообщение
Глазами. Где переход к следующему символу?
Спасибо. Исправлю.

C++
1
2
3
4
5
6
7
8
9
String String::up() const
{
   if ( st )
   {
      for ( ; *st ; ++st ) *st = toupper( *st );
   }
 
   return ( st );
}
Yandex
Объявления
24.08.2011, 21:33     Null pointer assignment.
Ответ Создать тему
Опции темы

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