Первая проблема:
const char *stringaling= (const char *) malloc(sizeof(uint32_t));
Несколько проблем на этой линии.
Прежде всего, вы не хотите объявлять stringaling
как const char *
; Вы не сможете изменить то, на что указывает stringaling
(IOW, *stringaling
не будет доступно для записи). Это важно, так как вы хотите скопировать содержимое другой строки в место, указанное stringaling
. Удалите ключевое слово const
.
Во-вторых, malloc(sizeof(uint32_t))
просто выделяет достаточно байтов (4) для этой конкретной строки, но не ясно, что вы подразумевали для выделения 4 байтов. При выделении памяти для массива (а строки - это массивы), явно укажите количество элементов , которые вы намереваетесь выделить.
Наконец, приведение результата malloc
считается плохой практикой в C. Приведение прекратит полезное диагностическое сообщение, если вы забудете включить stdlib.h или у вас нет прототипа для malloc
в области видимости. Согласно стандарту 1989 года, malloc
возвращает void *
, который может быть назначен любому другому типу указателя объекта без необходимости приведения. Это не так в C ++, поэтому здесь требуется приведение, но если вы пишете C ++, вам все равно следует использовать new
вместо malloc
.
Итак, измените эту строку на
char *stringaling = malloc(LEN); // or malloc(LEN * sizeof *stringaling), but
// in this case that's redundant since
// sizeof (char) == 1
где LEN - количество символов, которые вы хотите выделить.
Общая форма для malloc
звонка:
T *p = malloc (N * sizeof *p);
, где T
- базовый тип (int
, char
, float
, struct ...
и т. Д.), А N
- количество элементов типа T Вы хотите выделить. Поскольку тип выражения *p
равен T
, sizeof *p
== sizeof(T)
; если вы когда-либо измените тип p
, вам не нужно копировать это изменение в самом вызове malloc
.
Вторая проблема:
*stringaling = "fun";
Опять же, есть несколько проблем в игре. Во-первых, вы не можете присваивать строковые значения с помощью оператора =
. Строковые литералы являются выражениями массива, и в большинстве контекстов выражения массива имеют свой тип, неявно преобразуемый («распад») из «N-элементного массива T» в «указатель на T». Вместо того, чтобы копировать содержимое строкового литерала, вы просто назначаете указатель на первый символ в строке.
Что будет "работать" (см. Ниже), за исключением того, что вы разыменовываете stringaling
в назначении; тип выражения *stringaling
равен const char
(char
после внесения изменения, которое я указал выше), что несовместимо для присвоения с типом char *
. Если вы отбросите оператор разыменования и напишите
stringaling = "fun";
вы бы исправили ошибку во время компиляции, но теперь у вас есть другая проблема; как уже упоминалось выше, вы не скопировали содержимое строкового литерала "fun" в блок памяти, выделенный с помощью malloc
; вместо этого вы просто скопировали адрес строкового литерала в переменную stringaling
. При этом вы теряете динамически распределяемый блок, что приводит к утечке памяти.
Чтобы скопировать строку содержимое из одного места в другое, вам нужно использовать библиотечную функцию, например strcpy
или strncpy
или memcpy
, например:
strcpy(stringaling, "fun");
Если stringaling
не нужно жить в куче (например, вы используете его только в одной функции и освобождаете его перед возвратом), вы можете полностью избежать управления памятью, объявив ее как обычный массив char
и инициализируем его "fun":
char stringaling[] = "fun";
Это особый случай инициализации массива в объявлении, а не выражения присваивания, поэтому =
делает копирование содержимого строкового литерала в массив stringaling
. Однако это работает только в объявлении массива. Позже вы можете изменить массив с другими строковыми значениями (до 3 символов плюс терминатор 0), но вам придется снова использовать strcpy
:
strcpy(stringaling, "one");
Если вам не нужно изменять содержимое stringaling
, вы можете просто сделать
const char *stringaling = "fun";
Копирует адрес строкового литерала "fun" в переменную stringaling
.И поскольку попытка изменить содержимое строкового литерала вызывает неопределенное поведение, мы do хотим объявить stringaling
как const char *
в этом случае;это предотвратит случайное изменение строкового литерала.