c - 使用 char** 的项目(声明后初始化后)

标签 c arrays initialization pipe

正如cafhttps://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!!

您能帮我调用数组中的其他项目请求吗?

谢谢

最佳答案

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 放入 request 的第一个元素中。

char** command;
command=request;

足够简单; command 现在指向 request 的第一个(也是唯一的!)元素。

**command ? command++ : 0;

哎呀。您刚刚超出了 command (request) 的范围,因为 request 仅包含一个元素。然后,在下一行调用 SendCommand 时取消引用它,这会导致段错误。请注意,这里任何事情都可能发生,因为您正在调用 UB。

例如,如果您删除两个数组之间的代码,可能会发生以下情况:字符串“report molality H+”会被发送两次,因为将指针递增过去request 的边界很可能只是让您进入开始的 tmp

如果您想将所有 tmp 复制到 request 中,那么您需要确保两个数组的大小相同(或者至少, requesttmp 一样大)。

顺便说一句,这个三元表达式有点愚蠢:

**command ? command++ : 0;

你只关心一个分支,那么为什么要使用三元呢?偏好:

if(**command)
    command++;

也就是说,这不是检查数组边界的安全方法(正如您所发现的)。您将指针数组视为指向 char 的指针,即扫描直到找到 NULL 终止符。

数组没有 NULL 终止符,您最终只会越过其边界并调用未定义的行为,因此您需要单独跟踪大小并进行检查。

关于c - 使用 char** 的项目(声明后初始化后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11236444/

相关文章:

c - 如何使用 fread() 读取一行中的 2 个整数?

c - automake 的 subdir-objects 选项不起作用

c - 在 C 中解析 iCalendar 文件的工具集

arrays - 如何避免在 Bash `printf` 中使用空数组打印任何内容?

C++ 检查未初始化的迭代器

c - 从字符串中的特定情况中删除空格

javascript - 如何使用 JSON 在表中显示空白记录?

php - PHP 中两个 mysql 表的 Json 需要按层次结构输出

javascript - 声明具有多个字段的javascript数组

c++ - FILE* 在不同函数 c++ 中的初始化