C 如何将常量字符数组正确分配给结构?

C 如何将常量字符数组正确分配给结构?,c,arrays,struct,char,constants,C,Arrays,Struct,Char,Constants,我在将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

我在将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\u事务类型和此upd.xpbu\u更新类型分别返回整数(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:
    /   :
+MOD/DEL:
+   / Â +:
+MOD/DEL:
+MOD/:
/@Ea:
/Ea:
/ÃEa:
/0Fa:
/   :
所以,正如你所看到的,有时候这是正确的


我确信我的错误在结构赋值中。不幸的是,由于代码是专有软件,我无法对其进行更好的研究。

您必须同时更新类型和事务,然后使用strcpy并复制重要部分。您还必须编辑一些字符串:“INV\x00ADD\x00MOD\x00DEL\x00RPL”和“INS\x00OVR\x00MOV\x00DEL”

首先,这是线程之间共享的吗?如果是这样,那么您必须在关键部分保护对其成员的赋值,否则在打印变量时,可能会有另一个线程正在更新它,从而在打印时造成垃圾。我不确定
fprintf()
fflush()
的线程安全性,您也应该找到它,因为它可能是影响的另一个因素。

我怀疑问题在于您将数组的定义放在了哪里

您应该将它们放在全局地址空间中,或者将它们声明为静态的,以便能够在任务之间共享字符串的地址


或者,正如BlackBear建议的那样,分配内存并复制其中的子字符串。

您的代码不会检查upd.xpbu\u事务类型或upd.xpbu\u更新类型是否在正确的范围内

此外,为了线程安全,还需要使用互斥锁或其他东西

此外,这些字符串实际存储在哪个内存区域也不够清楚。不同的环境对于常量字符串的位置有不同的规则。确保它位于全局内存中,执行的两个线程都可以访问它。确保这一点的最简单方法是将字符串定义为任何函数外部的常量。如果它必须在函数中,则必须声明为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);
}

否,
fprintf(“%3.3s”)
的使用不需要nul-TERMINATOR。您能在调试器中逐步完成相关部分吗,要查看出错的地方和原因?我希望您更关注代码,而不是此处显示的语法和拼写。我无法单步调试调试程序,因为我只能在没有安装gdb的情况下运行一个特定的linux框。。xpbu_事务_类型和xpbu_更新_类型是全局的。它们来自于一个专有的api。谢谢,这就是问题所在。它们现在是静态字符数组
static char tx_types[]=“INV/ADD/MOD/DEL/RPL”;静态字符upd_类型[]=“INS/OVR/MOV/DEL”