Нужно ли нам инициализировать указатели внутри структуры

У нас есть указатели внутри структуры, нужно ли нам инициализировать указатели внутри структуры?

Я пробовал приведенный ниже код, включать это предложение ниже или нет, код работает хорошо. (Могли бы некоторые эксперты помочь здесь? Я прочитал код и обнаружил, что иногда он инициализирован, иногда нет, поэтому запутался и ищу/спрашиваю здесь.)

Ответ в этой ссылке кажется не упомянутым, инициализируйте этот указатель внутри структуры. инициализация-члена-структуры-с-указателями-c

#include "stdio.h"
#include "stdlib.h"

struct part{
    int num;
    char *name;
};

int main()
{
    struct part *p = (struct part*)malloc(sizeof(struct part));

    //Include this or not, this code all run well
    p->name = (char*)malloc(sizeof(char)); 

    p->num = 1;
    p->name = "ss";

    printf("%d, %s\n", p->num, p->name);

    return 0;
}



Если вы когда-нибудь разыменовываете указатели, вы должны убедиться, что они инициализированы, прежде чем делать это. Если вы никогда не разыменовываете их, почему указатель в структуре. Использование неинициализированного указателя является серьезной проблемой — избегайте этого.

Jonathan Leffler 19.03.2022 14:38

Вы вызываете (небольшую) утечку памяти, выделяя один байт, а затем перезаписывая полученный указатель другим указателем на строковый литерал.

Weather Vane 19.03.2022 14:38

Помните: p->name = "ss"; присваивает указатель — это не копия строки!

Jonathan Leffler 19.03.2022 14:38

@WeatherVane Спасибо за упоминание, да, мне нужно выделить больше байтов

Kumar 19.03.2022 14:47

Нет, ты еще больше просочишься. Посмотрите, что написал Джонатан. О, пожалуйста, не изменяйте код на лету. Сайт не является «скользящим учебным пособием».

Weather Vane 19.03.2022 14:47

Вы должны использовать strcpy() или аналогичную функцию для копирования строк в C.

Jonathan Leffler 19.03.2022 14:48

Понятно, strcpy(p->name, "ss"); Кстати, мне все еще нужно malloc p-> name перед использованием strcpy?

Kumar 19.03.2022 14:50

Да, и в случае это вы должны выделить достаточно байтов: strlen("ss") + 1

Weather Vane 19.03.2022 14:51

это отвечает на ваш вопрос?

n. 1.8e9-where's-my-share m. 19.03.2022 15:03

да, это помогает, может быть, я здесь ввожу в заблуждение, мне нужно использовать int* здесь, чтобы задать основной вопрос, который я хочу задать, что, если перед использованием нужно указать указатель malloc внутри структуры, или malloc самой структуры достаточно, теперь ответ кажется нам нужно выделить указатель внутри структуры, кроме самой структуры.

Kumar 19.03.2022 15:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, вы не должны этого делать, вы создаете утечку памяти, потому что вы выделяете память, а затем забываете значение указателя и не освобождаете ее.

Чтобы устранить утечку памяти:

p->name = malloc(1); //sizeof char is 1 by definition, and cast not needed
free(p->name);
p->name = "ss";

Однако, если вы посмотрите на это, должно быть ясно, что выделение 1 байта памяти, а затем немедленное ее освобождение, бессмысленно.


Возможно, вам нужна копия строки?

const char *initdata = "ss";
p->name = malloc(strlen(initdata)+1);
strcpy(p->name, initdata);
// Remember to free this at some point

В качестве альтернативы вы можете использовать initialize со строковым литералом, но тогда у вас должен быть указатель const char, потому что строковые литералы доступны только для чтения:

struct part{
    int num;
    const char *name;
};

Спасибо. Итак, прямо p->name = "ss"; или malloc + strcpy в этом случае все в порядке? (если не строковый литерал, скажем, int* внутри структуры, мы должны использовать malloc перед использованием, верно?)

Kumar 19.03.2022 15:14

@Kumar Если вам нужен указатель на исходную/исходную строку, назначьте указатель. Если вам нужна копия, используйте malloc+strcpy. Который зависит от остального кода, поэтому обычно только один правильный/хороший выбор.

hyde 19.03.2022 15:18

Другие вопросы по теме