Правильное заполнение указателя на символ - PullRequest
0 голосов
/ 08 мая 2019

У меня есть указатель на символ:

char* s = new char[150];

Теперь, как мне его заполнить? Это:

s="abcdef";

Дает предупреждение об устаревании преобразования между строковым литералом и char*, но обычно работает.

Это:

char* s = new[150]("abcdef");

Не работает, выдает ошибку.

Как это сделать правильно? Обратите внимание, что я хочу, чтобы выделение памяти имело размер 150 * (char) байтов и содержал "abcdef". Я знаю о malloc, но можно ли сделать с новым?

Это для задания, где я не могу использовать стандартную библиотеку.

Ответы [ 4 ]

7 голосов
/ 08 мая 2019

Эта последовательность утверждений

char* s = new char[150];
s="abcdef";

приводит к утечке памяти, потому что сначала память была выделена, а ее адрес был назначен указателю s, а затем указатель был переназначен с адресом строкового литерала "abcdef". Более того, строковые литералы в C ++ (напротив C) имеют типы постоянных символьных массивов.

Если вы выделили память для строки, вам следует скопировать строку в память, используя стандартную функцию C strcpy или стандартную функцию C strncpy.

Например

char* s = new char[150];
std::strcpy( s, "abcdef" );

Или

const size_t N = 150;
char* s = new char[N];
std::strncpy( s, "abcdef", N );
s[N-1] = '\0';

Или даже следующим образом

#include <iostream>
#include <cstring>

int main()
{
    const size_t N = 150;
    char *s = new char[N]{ '\0' };

    std::strncpy( s, "abcdef", N - 1 );

    std::cout << s << '\n';

    delete []s;
}

В любом случае лучше просто использовать стандартный класс std::string.

std::string s( "abcdef" );

или например

std::string s;
s.assign( "abcdef" );
3 голосов
/ 08 мая 2019

Основная процедура для создания области памяти для строки и последующего ее заполнения без использования стандартной библиотеки в C ++ выглядит следующим образом:

  • создать область памяти соответствующего размера с помощью new
  • использовать цикл для копирования символов из строки в новую область

Таким образом, исходный код будет выглядеть так:

// function to copy a zero terminated char string to a new char string.
// loop requires a zero terminated char string as the source.
char *strcpyX (char *dest, const char *source)
{
    char *destSave = dest;   // save copy of the destination address to return

    while (*dest++ = *source++);   // copy characters up to and including zero terminator.

    return destSave;  // return destination pointer per standard library strcpy()
}


// somewhere in your code

char *s1 = new char [150];

strcpyX (s1, "abcdef");
2 голосов
/ 08 мая 2019

Учитывая массив символов:

char * s = new char [256];

Вот как заполнить указатель :

std::fill(&s, &s + sizeof(s), 0);

Вот как заполнить массив :

std::fill(s, s+256, '\0');

Вот как назначить или скопировать текст в массив :

std::strcpy(s, "Hello");

Вы также можете использовать std::copy:

static const char text[] = "World";
std::copy(text, text + sizeof(text), s);

Помните, что указатель, массив и строка в стиле C - это разные понятия и объекты.

Изменить 1: Предпочитать std::string
В C ++ предпочитают использовать std::string для текста, а не символьных массивов.

std::string s;
s = "abcdef";
std::cout << s << "\n";
1 голос
/ 08 мая 2019

После выделения памяти для этой строки вы можете использовать strcpy для ее заполнения:

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