2013-10-12 3 views
3

У меня есть программа для обработки общего связанного списка. В одном случае я использую его для хранения строк. В функции, где я добавить новый узел в список я выполнить следующее (среди других вещей ..):Копирование указателя (а не его содержимого) с помощью memcpy

void list_append(list *list, void *element) 
{ 

    // create the new node... 
    listNode *node = (listNode *)malloc(sizeof(listNode)); 
    node->data = malloc(list->elementSize); // NOTE : elementSize is set to be sizeof(char *) 
    node->next = NULL; 
    memcpy(node->data, element, list->elementSize); //** 

    // rest of the insertion operation.... 

Теперь в функции, которая вызывает функцию list_append я выполнить следующие действия:

int numNames = 5; 
const char *names[] = { "David", "Kevin", "Michael", "Craig", "Jimi" }; //* 

int i; 
list list; 
list_new(&list, sizeof(char *), free_string ,compareString); 

char *name; 
for(i = 0; i < numNames; i++) { 
name = strdup(names[i]); 
list_append(&list, &name); //**** 
} 

Кроме того, у меня есть «сравнить метод» сравнить 2 строки:

int compareString(void *str1,void *str2) 
{ 

return strcmp(*(char **)str1 ,*(char **)str2); 
} 

Если да у меня есть несколько вопросов: 1) То, что копируется в й e, где memcpy находится в действии (строка // ** - указатель или содержимое? имеет ли это какое-либо отношение к тому, как хранятся данные для копирования в вызывающей функции (строка // *)? 2) Узел общего связанного списка определяется как: void * data; поэтому почему, когда я использую метод сравнения, я должен отдать его (char *) str1 .... будет ли отливка отличной, если бы я скопировал строку другим способом? Спасибо заранее (!!) заранее, Парень.

3) Другое дело - если я изменить операцию копирования, выполняемую тетсру в:

memcpy(node->data, element, strlen((char *)element) + 1); //** 

Он работает также - есть разница в 2 различных способах? если так - что лучше?

ответ

1

1) Вы копируете данные, содержащиеся в элементе, а не указатель. Если вы хотите скопировать указатель, вам необходимо передать & в качестве второго параметра.

2) Компилятор не знает, на что указывает void, поэтому вам нужно указать его тип.

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

+0

Спасибо большое за ваш ответ - пока я не понимаю (как мне кажется), как работает memcpy ... –

+0

Спасибо большое за ваш ответ, но я не понимаю (думаю), как работает memcpy ... В строке // **** я отправляю элемент как указатель на указатель, а количество копируемых байтов устанавливается равным 4 (sizeof (char *)), как указано в примечании ... строка, которую я передаю memcpy, указанную элемент на самом деле не 4 байта ... так что - что здесь копируется? как я его получаю (опять верьте мне, если я ошибаюсь) после того, как memcpy будет выполняться «оба» элемента и node-> данные указывают на местоположение, содержащее «оригинальную» строку ... Опять же, спасибо всем! –