Как правильно назначить массив const char для структуры? - PullRequest
0 голосов
/ 18 ноября 2011

У меня проблемы с сохранением массива const char в структуру, затем при вызове значения из структуры я не всегда получаю ожидаемое значение.

Ниже приведен код:

typedef struct
{
  char *update_type;
  char *transaction;
} TickType;

В потоке у меня есть:

const char tx_types[] = "INV/ADD/MOD/DEL/RPL";
const char upd_types[] = "INS/OVR/MOV/DEL";

tick->transaction = &tx_types[4*upd.xpbu_transaction_type];
tick->update_type = &upd_types[4*upd.xpbu_update_type];

Этот upd.xpbu_transaction_type и этот upd.xpbu_update_type возвращают целые числа (0-4) и(0-3) соответственно.В другом потоке мы печатаем в файл:

fprintf(out, "%3.3s/%3.3s:\n",tick->transaction, tick->update_type);
fflush(out);

Проблема в том, что при проверке выходного файла я вижу следующее:

+MOD/DEL:
+   / Â +:
+MOD/DEL:
+MOD/   :
    /@Ea:
    /<90>Ea:
    /Ã Ea:
    /0Fa:
    /   :

Так что, как вы можете видеть, это только правильноиногда.

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

Ответы [ 4 ]

1 голос
/ 18 ноября 2011

Прежде всего, это tick совместно используется потоками? Если это так, то вы должны защитить присвоение его членам в критическом разделе, в противном случае может быть вероятность, что переменная печатается, другой поток обновляет ее, вызывая мусор при печати. Я не уверен насчет безопасности потоков fprintf() и fflush(), вы тоже должны это выяснить, потому что это может быть еще одним фактором, который влияет.

1 голос
/ 18 ноября 2011

Я подозреваю, что проблема в том, где вы помещаете определения ваших массивов.

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

В качестве альтернативы, как BlackBear предложил выделить память и скопировать туда подстроку.

0 голосов
/ 18 ноября 2011

Ваш код не проверяет, что upd.xpbu_transaction_type или upd.xpbu_update_type находится в допустимых диапазонах.

Также вам необходимо использовать Mutex или что-то другое для безопасности потоков.

Также недостаточно ясно, в какой области памяти эти строки на самом деле хранятся. В разных средах существуют разные правила относительно того, где будут расположены строки const.Убедитесь, что он находится в глобальной памяти, которая всегда доступна обоим потокам выполнения.Самый простой способ убедиться в этом - определить строки как const вне любой функции.Если оно должно быть в функции, оно должно быть объявлено как static const.

В зависимости от вашей среды достаточно простого:

Поток A:

/* validate upd values, etc*/
switch (upd.xpbu_transaction_type)
{
...
default:
  xpbu_tt = 0;
}

...
taskLock();
tick->transaction = &tx_types[4*xpbu_tt];
tick->update_type = &upd_types[4*xpbu_ut];
taskUnlock();

Тема B:

While (1)
{
...
taskLock();
t = tick->transaction;
u = tick->update_type;
taskUnlock();
fprintf(out, "%3.3s/%3.3s:\n",t,u);
fflush(out);
}
0 голосов
/ 18 ноября 2011

Вы должны выполнить malloc как update_type, так и транзакции, затем использовать strcpy и скопировать важную часть.Вы также должны немного отредактировать свои строки: "INV \ x00ADD \ x00MOD \ x00DEL \ x00RPL" и "INS \ x00OVR \ x00MOV \ x00DEL"

...