Как назначить строковое значение в C из void *? - PullRequest
0 голосов
/ 26 октября 2011

Я реализую CMap в C, и часть этого влечет за собой хранение информации в структуре типа связанного списка, которой я вручную управляю памятью. Таким образом, первые 4 байта этого struct являются указателями на следующие struct, следующий раздел - это строка (ключ), а последний раздел - это значение.

Скажите void *e = ptr определяет один такой связанный список. Затем ptr + 4 относится к началу раздела строки. Я хочу присвоить это строковое значение другой строке, и на данный момент я сделал следующее:

char *string = (char *)ptr + 4;

Однако я не думаю, что это правильно.

Ответы [ 3 ]

0 голосов
/ 26 октября 2011

Просто ссылочная структура вместо вычисления смещений.

//if data is structured this way
struct struct_list_el
{
  struct list_el * next; 
  char* str;
  int value;
};
typedef struct struct_list_el list_el;

// than from void_pointer
list_el* el;
el = (list_el*) void_pointer;

char * string;
string = el->str;
0 голосов
/ 26 октября 2011

@ ralu правильно, что вы должны использовать структуру. Но вы также должны быть очень осторожны при копировании строк. В C нет строкового объекта первого класса, как в C ++, Java, Python, и, в общем, во всем остальном. :)

В C символьные указатели (char*) часто используются в качестве строк, но на самом деле они являются просто указателями на нулевые концевые массивы байтов в памяти где-либо. Копирование указателя на символ не совпадает с копированием основного массива символов. Для этого вам необходимо выделить память для символов копии. Эта память может находиться в стеке (локальный массив), в куче (созданной с помощью malloc) или в каком-либо другом буфере.

Вам нужно измерить длину строки, прежде чем что-либо делать, чтобы убедиться, что целевой буфер может ее содержать. Не забудьте добавить один к длине, чтобы было место для завершающего нуля.

Также обратите внимание, что стандартные библиотечные функции (strlen, strcpy, strncpy, strcat, snprintf, strdup и т. Д.) Немного несовместимы друг с другом в отношении завершающего нуля. Например, strlen возвращает количество символов, исключая завершающий ноль, поэтому буферы должны быть на один байт больше, чем те, которые он возвращает для хранения вещей. Кроме того, strncpy не гарантирует нулевое завершение, в то время как snprintf делает. Неправильное использование этих функций и строк C в целом является причиной значительного числа нарушений безопасности (не говоря уже об ошибках) в современных компьютерных системах.

Если вы не создаете или не используете надежную библиотеку, манипуляции со строками и списками в C утомительны и подвержены ошибкам. Вы можете понять, почему были изобретены C ++ и все эти другие языки.

0 голосов
/ 26 октября 2011

Если вы хотите указать на одну и ту же строку, ваш код в порядке, при условии, что указатели всегда имеют ширину 4 байта.

Если вы хотите скопировать содержимое строки, используйте malloc и strcpy для создания новой строки.

...