写入分配的2D阵列

时间:2017-10-31 11:34:48

标签: c arrays arduino malloc

我正在尝试使用固定大小字符串的可变长度数组创建一个结构。

struct foo_query{
  char tag[10];
  int value_count;
  char * values[VAL_SIZE];
};

现在,我想创建这些结构的数组,并为值分配一些内存:

#define buffer(a) (char *) malloc(sizeof(char[a][VAL_SIZE]))
foo_query queries[total_queries] = {
    {"FOO", 25, buffer(25)},
    {"BAR", 21, buffer(21)}
};
#undef buffer

最后,我想实际将一些数据写入值。

query_index = 0;
for(int i = 0; i < queries.value_count; i++){
    strncpy(queries[query_index].values[i], "Hello", VAL_SIZE);
    Serial.outln("success");
}

但最后一点失败了。 success打印一次或两次,然后一切都停止。

据我所知,内存已经分配,​​我没有溢出任何东西,为什么代码会崩溃?

1 个答案:

答案 0 :(得分:0)

基本上你的内存分配是错误的。

foo_query queries[total_queries] = {
    {"FOO", 25, buffer(25)},
    {"BAR", 21, buffer(21)}
};

当您在上面创建queries时,您只填充values的第一个元素,因为您定义它的方式,valueschar *的数组

i大于0时,如果要将值放入该数组,则会复制到未分配的指针。

strncpy(queries[query_index].values[i], "Hello", VAL_SIZE);

i大于0时,queries[query_index].values[i]可能为NULL,或者它可能指向内存的某些部分。无论哪种方式,它都会导致未定义的行为,并且您的代码会随机崩溃。

鉴于您尝试将VAL_SIZE个字符复制到其中,看起来您实际上错误地定义了values。而不是char *的数组,您看起来更有可能寻找指向char VAL_SIZE数组的指针?如果是这种情况,您需要将其定义为:

char (* values)[VAL_SIZE];

它也适合你使用malloc分配的相当奇怪的内存量,它看起来更加清晰malloc(sizeof(char[VAL_SIZE})*(a))。 (注意:总是将宏参数包装在括号中,以确保您没有疯狂的优先级问题,即buffer(10+10)变为malloc(sizeof(char[VAL_SIZE})*10+10)而没有括号。)

你还应该加入

queries[query_index].values[i][VAL_SIZE-1]='\0';

strncpy之后,只是为了确保复制的字符串太大而不适合,你的字符串也终止NUL。