正如 caf 在https://stackoverflow.com/a/1113041/1354779中谈到的那样, 当声明变量初始化已声明的数组时,有一种方法可以使用初始化器。 这很好,我现在想知道是否有办法逐个使用数组中的每个项目。
我用它来通过管道传递一个命令列表,我知道这个有效:
char* script[]={"report blabla","report bla"};
char line[200];
char** command;
for (command = script ; **command ; **command ? command++ : 0){
if (**command){
SendCommand(*command, line, sizeof(line));
}
}
但是当我尝试下面的代码时,我在pipe_GWB9.exe中的0x778915de处出现“未处理的异常:0xC0000005:访问冲突读取位置0xcccccccc”:
char* request[] = {"report watact"};
char line[200];
// [...] Other code [...]
static const char *tmp[8] =
{
"report molality H+",
"report molality Cl-",
"report molality Ca++",
"report molality Mg++",
"report molality K+",
"report molality Fe++",
"report molality SO4--",
"report molality Na+"
};
memcpy(request, tmp, sizeof request);
char** command;
command=request;
SendCommand(*command, line, sizeof(line));
// Until here, everything works great.
**command ? command++ : 0;
SendCommand(*command, line, sizeof(line));
// But THAT doesn't work!!
您是否可以帮我调用数组请求中的其他项?
谢谢
答案 0 :(得分:1)
char* request[] = {"report watact"};
request
是一个指向char的指针数组,包含1个元素。
static const char *tmp[8] =
{
"report molality H+",
"report molality Cl-",
"report molality Ca++",
"report molality Mg++",
"report molality K+",
"report molality Fe++",
"report molality SO4--",
"report molality Na+"
};
tmp
是一个指向char
的指针数组,包含8个元素。
memcpy(request, tmp, sizeof request);
您将sizeof request == 4
中的前四个字节(假设tmp
)复制到request
,即将tmp
的第一个元素复制到{{1}的第一个元素中1}}。
request
足够简单; char** command;
command=request;
现在指向command
的第一个(也是唯一的!)元素。
request
糟糕。您刚刚超出**command ? command++ : 0;
(command
)的范围,因为request
只包含一个元素。然后在下一行调用request
时取消引用它,这会给你seg错误。请注意,这里可能发生任何事情,因为您正在调用UB。
例如,如果切断两个数组之间的代码,可能会发生的事情是字符串SendCommand
被发送两次因为将指针递增超过{{1}的范围很可能只是把你带到开头"report molality H+"
。
如果要将request
复制到tmp
,则需要确保两个数组的大小相同(或至少tmp
与request
一样大request
)。
顺便说一下,这个三元表达式有点傻:
tmp
你只关心一个分支,为什么要使用三元组呢?喜欢:
**command ? command++ : 0;
也就是说,这不是一种检查数组边界的安全方法(正如您所发现的那样)。您正在将指针数组视为指向char的指针,即扫描直到找到NULL终止符。
数组没有NULL终止符,你只是走过它的边界并调用未定义的行为,所以你需要分别跟踪大小并检查它。