чем причина?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct product {
char *name;
float price;
};
struct product *createProduct(char *name, float price) {
struct product *pr = malloc(sizeof(struct product));
pr->price = price;
strcpy(pr->name, name);
return pr;
}
int main() {
struct product *milk = createProduct("milk", 10.0);
printf("%f\n", milk->price);
free(milk);
return 0;
}
asan тебе в руки
Pr>name это указатель, и куда он указывает?
По мне, вы выделили память под структуру, но в ней float и указатель char. Нужно сделать выделение ещё для строки, или иметь заведомо длинное поле для копирования символов.
точно,спасибо, я забыл память под строку выделить
Ты возвращаешь указатель на локальную переменную
а почему это плохо?
вообще, потому, что она лежит на стэке, и при выходе из зоны видимости указатель будет указывать туда, куда не следует
Держи #include <stdio.h> #include <stdlib.h> #include <string.h> struct product { float price; size_t name_size; char name[]; }; struct product *createProduct(char *name, float price, size_t name_size) { struct product *pr = malloc(sizeof *pr + sizeof *(struct product *){0}->name * name_size); pr->price = price; pr->name_size = name_size; strcpy(pr->name, name); return pr; } int main() { struct product *milk = createProduct("milk", 10.0, 5); printf("%f\n", milk->price); free(milk); return 0; }
Норм, но сайз строки я бы хранил. Раз flexible array member
Да, было бы неплохо, добавил
Где?
И почему происходит сегфолт?
почитай ниже
В коде возвращается указатель на выделенную память. После выхода из ф-ии, он будет указывать туда, куда нужно. Сег происходит не из-за этого.
Наверное там уб, как считаешь?
я даже не понимаю, о чем ты говоришь. Вернись и перечитай все сообщения. Хватит бороться с мельницами
Считаю что копирование идёт по указателю, который дали strcpy
А в какую область памяти?
Наверное в дерьмовую, т.к. в указателе именно оно и лежит
Скорее всего на дебаге в гцц лежит 0
Раковая херня бтв. Мемори патерны из мсвц лучше
Он разве флаг для анонимной памяти в mmap применяет? Сомнительно. Или типа компиль умный и сам патчит на 0?
Гцц в дебаге для не инициализированной памяти везде пихает 0
В область которая указана в коде, т.е что было указано. Указано было ничего, от этого сег. Я так думаю. Ну если не считать что под строку не выделена память.
На дебаге 0, на релизе рандом мусор void foo() { int i; printf("%d", i); }
Чем char name[]; лучше char *name; ?
Указатель не храним
я так понимаю, ничем. Семантически-то эквивалентно
Ты рил настолько отсталый, что не в состоянии прочитать сообщение выше?
Стикер
Какой же бред, вот эти фразочки "массив - это указатель на первый элемент" Ты понимаешь, что у тебя в голове прям говно? Кто так постарался?
успокойся, пожалуйста
Как только срань подобную перестанешь писать, так сразу
так ты возьми да скажи, как правильно. А то пока только клоуна из себя строишь
Умножение размера типа элемента fam на количество элементов. Чтобы узнать размер типа берётся размер элемента fam по указателю, являющимся компаунд литералом
Миллиард раз уже в этом чате обсуждали этот вопрос
так обсуди миллиард первый раз. Либо кинь линк на последнее обсуждение.
Как я понял там без указателя просто байты хранятся, т.к. в struct все последовательно, значит char* name = *pr + sizof(float) + sizeof(size_t)
https://t.me/lame_c/119547 https://t.me/lame_c/116954 https://t.me/lame_c/93325 Ознакамливайся
ааа, так вот о чем ты. Мол, массив не является лишь указателем на первый элемент мне кажется, ты просто путаешь уровни абстракций. Динамический/статический массив и правда является непрерывным участком памяти с определенной длиной, вмещающий в себя элементы одного типа. А вот как длина будет выражена на практике - дело уже иное. Хоть рядышком храни, хоть введи терминатор. то есть, по сути, банально пытаешься душить, основываясь на логической ошибке. Сложно же было твой поток сознания распутать, однако
Мда, нихрена ты не понял, там по одной из ссылок я привожу определение массива, перечитай, и подумай ещё раз. Массив - в принципе не может являться указателем на его первый элемент. При чём тут вообще терминатор? При чём тут уровни абстракции? Язык си это и есть уровень абстракции. Так что снова гадишь мимо.
Ещё раз массив НЕ реализуется через голый указатель. Вон в случае fam нет указателя, в случае автоматических и статических массивов нет указателя, и о чудо, даже в динамической памяти можно создать объект типа массив, от которого можно получить адрес. Ты не понимаешь одного - массив это про тип и про структуру данных, а не про указатель на какую-то область памяти.
Ты не понял скорее всего в силу своего скудоумия, стоит прочитать стандарт языка, где великолепно описано, что такое тип массив, какие у него свойства, как происходит работа с ним, и откуда берётся в итоге указатель на его первый элемент.
нет, думаю, проблема все же в том, что ты демагог, основывающий свои доводы на ошибках, которые хуй просто так обнаружишь:) спорим, если я пойду в стандарт и почитаю про член структуры вида char name[], я там увижу, что это эквивалентно char* name?
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply. Howev er, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it. Это, пожалуй, всё, что сказано про fam в стандарте.
Зачем скобки?
2 + 2 * 2 = 8 2 + (2 * 2) = 6
почти поверил
Это в каком классе такому учат? Коррекции?
В C не так?
В обоих случаях 6. Иди в школу, тебе это необходимо.
Как это работает? sizeof *(struct product *){0}->name И как будет выглядеть создание этого? struct product { float price; size_t name_size; char name[]; char description[]; };
Если у тебя два поля юзай просто поинтеры
1. Я же тебе уже написал тут https://t.me/lame_c/132333 2. Никак не будет, fam может быть только один и он должен быть последним полем структуры.
Корректно ли делать так? struct product { float price; size_t name_size; char *name; char description[]; };
Тут либо char* name; char* description; либо сhar name[260]; char description[260];
Если сайзоф применяется к объекту, то скобки не нужны
Стикер
Ну а что поделать, единственный нормальный вариант, тип в сайзофе писать совсем не комильфо.
Телеграмм вроде умеет конвертировать голос в текстовое сообщение
у него ангельский голосочек
и картавит возбуждающе
Обсуждают сегодня