Лучше практиковать strcpy () или указывать на другую структуру данных? - PullRequest
4 голосов
/ 25 июня 2010

Поскольку код всегда легче увидеть ...

Мой анализатор заполняет этот объект:

typedef struct pair {
 char* elementName;
 char* elementValue;
} pair;

Мой интерпретатор хочет прочитать этот объект и заполнить его:

typedef struct thing {
 char* label;
} thing;

Должен ли я сделать это:

thing.label = pair.elementName;

или это:

thing.label = (char*)malloc(strlen(pair.elementName)+1);
strcpy(thing.label, pair.elementName);

РЕДАКТИРОВАТЬ: Да, я думаю, я должен был указать, что будет делать остальная часть программыобъекты.В конце концов мне нужно будет сохранить «пару» в файл.Поэтому, когда thing.label изменен, то в какой-то момент pair.elementName необходимо изменить для соответствия.Итак, я думаю, что первый - лучший способ сделать это?

Ответы [ 7 ]

3 голосов
/ 25 июня 2010

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

1 голос
/ 26 июня 2010

Вот некоторые вещи, которые нужно знать, чтобы ответить на вопрос:

  • Какой объект будет «владеть» строкой?Или оба будут владеть своей строкой (в этом случае необходима «глубокая» копия)?
  • - это время жизни объектов pair и thing, связанных каким-либо образом, - будет ли один объект всегда «пережить»другой?Владеет ли один из этих объектов другим?

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

Не то, чтобы это были единственно возможные ответы - только пара простых.

1 голос
/ 25 июня 2010

Я бы лично сделал первое, но это компромисс. В первом случае нет необходимости выделять новую память и копировать в нее данные, а во втором избегается путаница с псевдонимами, поскольку thing.label и pair.elementName указывают на отдельные адреса памяти, что означает, что вам нужно освободить оба из них (с помощью прежде вы должны быть уверены, что освободите ровно один, чтобы избежать утечки памяти или двойного освобождения)

0 голосов
/ 26 июня 2010

Я не хочу быть полицейским, но, пожалуйста, используйте strncpy() вместо strcpy().

char* strncpy(char *s1, const char *s2, size_t n); 

Функция strncpy копирует не более n символов из s2 в s1.

0 голосов
/ 26 июня 2010

Если вы хотите сделать копию и выполнить всю очистку впоследствии ... в C вы должны сделать это:

thing.label = strdup(pair.elementName);
0 голосов
/ 25 июня 2010

Ответ, как всегда, «Это зависит». Если все, что вы делаете со «скопированным» значением, - это его чтение, то, вероятно, можно просто скопировать адрес указателя (т. Е. Первый), если вы правильно очистите. Если «скопированное» значение будет изменено каким-либо образом, вы захотите создать новую строку целиком (т. Е. Последнюю), чтобы избежать любых непреднамеренных побочных эффектов, вызванных изменением «исходного» значения (если только конечно, это как раз тот желаемый эффект).

0 голосов
/ 25 июня 2010

С точки зрения независимости "объекта", вероятно, лучше сделать копию данных, чтобы избежать проблем с висящими указателями.

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

...