У нас есть указатели внутри структуры, нужно ли нам инициализировать указатели внутри структуры?
Я пробовал приведенный ниже код, включать это предложение ниже или нет, код работает хорошо. (Могли бы некоторые эксперты помочь здесь? Я прочитал код и обнаружил, что иногда он инициализирован, иногда нет, поэтому запутался и ищу/спрашиваю здесь.)
Ответ в этой ссылке кажется не упомянутым, инициализируйте этот указатель внутри структуры. инициализация-члена-структуры-с-указателями-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;
}
Вы вызываете (небольшую) утечку памяти, выделяя один байт, а затем перезаписывая полученный указатель другим указателем на строковый литерал.
Помните: p->name = "ss";
присваивает указатель — это не копия строки!
@WeatherVane Спасибо за упоминание, да, мне нужно выделить больше байтов
Нет, ты еще больше просочишься. Посмотрите, что написал Джонатан. О, пожалуйста, не изменяйте код на лету. Сайт не является «скользящим учебным пособием».
Вы должны использовать strcpy()
или аналогичную функцию для копирования строк в C.
Понятно, strcpy(p->name, "ss"); Кстати, мне все еще нужно malloc p-> name перед использованием strcpy?
Да, и в случае это вы должны выделить достаточно байтов: strlen("ss") + 1
это отвечает на ваш вопрос?
да, это помогает, может быть, я здесь ввожу в заблуждение, мне нужно использовать int* здесь, чтобы задать основной вопрос, который я хочу задать, что, если перед использованием нужно указать указатель malloc внутри структуры, или malloc самой структуры достаточно, теперь ответ кажется нам нужно выделить указатель внутри структуры, кроме самой структуры.
Нет, вы не должны этого делать, вы создаете утечку памяти, потому что вы выделяете память, а затем забываете значение указателя и не освобождаете ее.
Чтобы устранить утечку памяти:
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 Если вам нужен указатель на исходную/исходную строку, назначьте указатель. Если вам нужна копия, используйте malloc+strcpy. Который зависит от остального кода, поэтому обычно только один правильный/хороший выбор.
Если вы когда-нибудь разыменовываете указатели, вы должны убедиться, что они инициализированы, прежде чем делать это. Если вы никогда не разыменовываете их, почему указатель в структуре. Использование неинициализированного указателя является серьезной проблемой — избегайте этого.