основной вопрос с ++, динамическое распределение памяти - PullRequest
0 голосов
/ 21 января 2010

Предположим, у меня есть класс

class person
{
char* name;
public:
void setname(const char*);
};
void person::setname(const char* p)
{
name=new char[strlen(p)];
strcpy(name,p);
name[strlen(p)]='\0';
}

Мой вопрос о линии name = new char [strlen (p)]; предположим, что указатель p указывает на строку, т.е. «zia», теперь strlen (p) вернет 3, это означает, что у нас есть массив из 4 символов, т.е. char [3], теперь я копирую строку в имя и в 4-м месте я поставить нулевой символ, что не так с этим ?????

Ответы [ 8 ]

5 голосов
/ 21 января 2010

Вы говорите:

у нас есть массив из 4 символов, т.е. символ [3]

Удивительно, но char [3] - это массив из трех символов, а не FOUR!

3 голосов
/ 21 января 2010

Вы ДОЛЖНЫ выделить еще один символ для нулевого терминатора:

name = new char[strlen(p) + 1];
2 голосов
/ 21 января 2010

Здесь вы ошибаетесь:

теперь strlen (p) вернет 3, это означает, что у нас есть массив из 4 символов, т.е. char [3]

Массив из 4 символов: char[4]; если вы выделяете динамически, вам нужно будет передать 4 на operator new или, в общем:

name=new char[strlen(p)+1];
2 голосов
/ 21 января 2010

Вы должны выделить strlen (p) +1 символов:

name = new char[strlen(p)+1];
2 голосов
/ 21 января 2010

Вам нужно выделить еще одну позицию памяти для символа \ 0, в противном случае, когда вы сделаете это name[strlen(p)]='\0';, вы получите ошибку сегментации. В основном делать new char[strlen(p) + 1].

2 голосов
/ 21 января 2010

Проблемы

  1. Вы никогда не delete[] name;, поэтому каждый раз, когда пользователь вызывает setname(), вы пропускаете массив.
  2. Для размещения дополнительных '\0' необходимо выделить strlen(p)+1 элементов.
1 голос
/ 21 января 2010

Многие люди упоминали лекарство от немедленной проблемы, с которой вы столкнулись. Тем не менее, они почти оказали вам медвежью услугу. Если у вас нет действительно веской причины поступить иначе, вероятно, вам следует определить имя как и std::string и использовать его оператор присваивания для правильной обработки задания.

Если у вас есть действительно веская причина избегать использования std::string, то вам следует создать собственный класс строки и использовать его вместо этого. По крайней мере, на мой взгляд, написание кода, как у вас, с динамическим распределением и strcpy повсюду - просто плохая идея. Даже в лучшем случае его трудно читать, он подвержен множеству глупых ошибок, и по существу невозможно сделать что-либо, близкое к исключению, безопасным.

1 голос
/ 21 января 2010
void person::setname(const char* p)
{

name=new char[strlen(p) + 1]; // make a room to have null character 
strcpy(name,p);
name[strlen(p)]='\0';

}

индекс массива начинается с 0, поэтому максимальный индекс для массива размером = 5 равен arr [4].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...